📄 be_aas_route.c
字号:
aasworld.areavisibility = (byte **) GetClearedMemory(aasworld.numareas * sizeof(byte *));
aasworld.decompressedvis = (byte *) GetClearedMemory(aasworld.numareas * sizeof(byte));
for (i = 0; i < aasworld.numareas; i++)
{
botimport.FS_Read(&size, sizeof(size), fp );
if (size) {
aasworld.areavisibility[i] = (byte *) GetMemory(size);
botimport.FS_Read(aasworld.areavisibility[i], size, fp );
}
}
*/
//
botimport.FS_FCloseFile(fp);
return qtrue;
} //end of the function AAS_ReadRouteCache
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#define MAX_REACHABILITYPASSAREAS 32
void AAS_InitReachabilityAreas(void)
{
int i, j, numareas, areas[MAX_REACHABILITYPASSAREAS];
int numreachareas;
aas_reachability_t *reach;
vec3_t start, end;
if (aasworld.reachabilityareas)
FreeMemory(aasworld.reachabilityareas);
if (aasworld.reachabilityareaindex)
FreeMemory(aasworld.reachabilityareaindex);
aasworld.reachabilityareas = (aas_reachabilityareas_t *)
GetClearedMemory(aasworld.reachabilitysize * sizeof(aas_reachabilityareas_t));
aasworld.reachabilityareaindex = (int *)
GetClearedMemory(aasworld.reachabilitysize * MAX_REACHABILITYPASSAREAS * sizeof(int));
numreachareas = 0;
for (i = 0; i < aasworld.reachabilitysize; i++)
{
reach = &aasworld.reachability[i];
numareas = 0;
switch(reach->traveltype & TRAVELTYPE_MASK)
{
//trace areas from start to end
case TRAVEL_BARRIERJUMP:
case TRAVEL_WATERJUMP:
VectorCopy(reach->start, end);
end[2] = reach->end[2];
numareas = AAS_TraceAreas(reach->start, end, areas, NULL, MAX_REACHABILITYPASSAREAS);
break;
case TRAVEL_WALKOFFLEDGE:
VectorCopy(reach->end, start);
start[2] = reach->start[2];
numareas = AAS_TraceAreas(start, reach->end, areas, NULL, MAX_REACHABILITYPASSAREAS);
break;
case TRAVEL_GRAPPLEHOOK:
numareas = AAS_TraceAreas(reach->start, reach->end, areas, NULL, MAX_REACHABILITYPASSAREAS);
break;
//trace arch
case TRAVEL_JUMP: break;
case TRAVEL_ROCKETJUMP: break;
case TRAVEL_BFGJUMP: break;
case TRAVEL_JUMPPAD: break;
//trace from reach->start to entity center, along entity movement
//and from entity center to reach->end
case TRAVEL_ELEVATOR: break;
case TRAVEL_FUNCBOB: break;
//no areas in between
case TRAVEL_WALK: break;
case TRAVEL_CROUCH: break;
case TRAVEL_LADDER: break;
case TRAVEL_SWIM: break;
case TRAVEL_TELEPORT: break;
default: break;
} //end switch
aasworld.reachabilityareas[i].firstarea = numreachareas;
aasworld.reachabilityareas[i].numareas = numareas;
for (j = 0; j < numareas; j++)
{
aasworld.reachabilityareaindex[numreachareas++] = areas[j];
} //end for
} //end for
} //end of the function AAS_InitReachabilityAreas
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_InitRouting(void)
{
AAS_InitTravelFlagFromType();
//
AAS_InitAreaContentsTravelFlags();
//initialize the routing update fields
AAS_InitRoutingUpdate();
//create reversed reachability links used by the routing update algorithm
AAS_CreateReversedReachability();
//initialize the cluster cache
AAS_InitClusterAreaCache();
//initialize portal cache
AAS_InitPortalCache();
//initialize the area travel times
AAS_CalculateAreaTravelTimes();
//calculate the maximum travel times through portals
AAS_InitPortalMaxTravelTimes();
//get the areas reachabilities go through
AAS_InitReachabilityAreas();
//
#ifdef ROUTING_DEBUG
numareacacheupdates = 0;
numportalcacheupdates = 0;
#endif //ROUTING_DEBUG
//
routingcachesize = 0;
max_routingcachesize = 1024 * (int) LibVarValue("max_routingcache", "4096");
// read any routing cache if available
AAS_ReadRouteCache();
} //end of the function AAS_InitRouting
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_FreeRoutingCaches(void)
{
// free all the existing cluster area cache
AAS_FreeAllClusterAreaCache();
// free all the existing portal cache
AAS_FreeAllPortalCache();
// free cached travel times within areas
if (aasworld.areatraveltimes) FreeMemory(aasworld.areatraveltimes);
aasworld.areatraveltimes = NULL;
// free cached maximum travel time through cluster portals
if (aasworld.portalmaxtraveltimes) FreeMemory(aasworld.portalmaxtraveltimes);
aasworld.portalmaxtraveltimes = NULL;
// free reversed reachability links
if (aasworld.reversedreachability) FreeMemory(aasworld.reversedreachability);
aasworld.reversedreachability = NULL;
// free routing algorithm memory
if (aasworld.areaupdate) FreeMemory(aasworld.areaupdate);
aasworld.areaupdate = NULL;
if (aasworld.portalupdate) FreeMemory(aasworld.portalupdate);
aasworld.portalupdate = NULL;
// free lists with areas the reachabilities go through
if (aasworld.reachabilityareas) FreeMemory(aasworld.reachabilityareas);
aasworld.reachabilityareas = NULL;
// free the reachability area index
if (aasworld.reachabilityareaindex) FreeMemory(aasworld.reachabilityareaindex);
aasworld.reachabilityareaindex = NULL;
// free area contents travel flags look up table
if (aasworld.areacontentstravelflags) FreeMemory(aasworld.areacontentstravelflags);
aasworld.areacontentstravelflags = NULL;
} //end of the function AAS_FreeRoutingCaches
//===========================================================================
// update the given routing cache
//
// Parameter: areacache : routing cache to update
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_UpdateAreaRoutingCache(aas_routingcache_t *areacache)
{
int i, nextareanum, cluster, badtravelflags, clusterareanum, linknum;
int numreachabilityareas;
unsigned short int t, startareatraveltimes[128]; //NOTE: not more than 128 reachabilities per area allowed
aas_routingupdate_t *updateliststart, *updatelistend, *curupdate, *nextupdate;
aas_reachability_t *reach;
aas_reversedreachability_t *revreach;
aas_reversedlink_t *revlink;
#ifdef ROUTING_DEBUG
numareacacheupdates++;
#endif //ROUTING_DEBUG
//number of reachability areas within this cluster
numreachabilityareas = aasworld.clusters[areacache->cluster].numreachabilityareas;
//
aasworld.frameroutingupdates++;
//clear the routing update fields
// Com_Memset(aasworld.areaupdate, 0, aasworld.numareas * sizeof(aas_routingupdate_t));
//
badtravelflags = ~areacache->travelflags;
//
clusterareanum = AAS_ClusterAreaNum(areacache->cluster, areacache->areanum);
if (clusterareanum >= numreachabilityareas) return;
//
Com_Memset(startareatraveltimes, 0, sizeof(startareatraveltimes));
//
curupdate = &aasworld.areaupdate[clusterareanum];
curupdate->areanum = areacache->areanum;
//VectorCopy(areacache->origin, curupdate->start);
curupdate->areatraveltimes = startareatraveltimes;
curupdate->tmptraveltime = areacache->starttraveltime;
//
areacache->traveltimes[clusterareanum] = areacache->starttraveltime;
//put the area to start with in the current read list
curupdate->next = NULL;
curupdate->prev = NULL;
updateliststart = curupdate;
updatelistend = curupdate;
//while there are updates in the current list
while (updateliststart)
{
curupdate = updateliststart;
//
if (curupdate->next) curupdate->next->prev = NULL;
else updatelistend = NULL;
updateliststart = curupdate->next;
//
curupdate->inlist = qfalse;
//check all reversed reachability links
revreach = &aasworld.reversedreachability[curupdate->areanum];
//
for (i = 0, revlink = revreach->first; revlink; revlink = revlink->next, i++)
{
linknum = revlink->linknum;
reach = &aasworld.reachability[linknum];
//if there is used an undesired travel type
if (AAS_TravelFlagForType_inline(reach->traveltype) & badtravelflags) continue;
//if not allowed to enter the next area
if (aasworld.areasettings[reach->areanum].areaflags & AREA_DISABLED) continue;
//if the next area has a not allowed travel flag
if (AAS_AreaContentsTravelFlags_inline(reach->areanum) & badtravelflags) continue;
//number of the area the reversed reachability leads to
nextareanum = revlink->areanum;
//get the cluster number of the area
cluster = aasworld.areasettings[nextareanum].cluster;
//don't leave the cluster
if (cluster > 0 && cluster != areacache->cluster) continue;
//get the number of the area in the cluster
clusterareanum = AAS_ClusterAreaNum(areacache->cluster, nextareanum);
if (clusterareanum >= numreachabilityareas) continue;
//time already travelled plus the traveltime through
//the current area plus the travel time from the reachability
t = curupdate->tmptraveltime +
//AAS_AreaTravelTime(curupdate->areanum, curupdate->start, reach->end) +
curupdate->areatraveltimes[i] +
reach->traveltime;
//
if (!areacache->traveltimes[clusterareanum] ||
areacache->traveltimes[clusterareanum] > t)
{
areacache->traveltimes[clusterareanum] = t;
areacache->reachabilities[clusterareanum] = linknum - aasworld.areasettings[nextareanum].firstreachablearea;
nextupdate = &aasworld.areaupdate[clusterareanum];
nextupdate->areanum = nextareanum;
nextupdate->tmptraveltime = t;
//VectorCopy(reach->start, nextupdate->start);
nextupdate->areatraveltimes = aasworld.areatraveltimes[nextareanum][linknum -
aasworld.areasettings[nextareanum].firstreachablearea];
if (!nextupdate->inlist)
{
// we add the update to the end of the list
// we could also use a B+ tree to have a real sorted list
// on travel time which makes for faster routing updates
nextupdate->next = NULL;
nextupdate->prev = updatelistend;
if (updatelistend) updatelistend->next = nextupdate;
else updateliststart = nextupdate;
updatelistend = nextupdate;
nextupdate->inlist = qtrue;
} //end if
} //end if
} //end for
} //end while
} //end of the function AAS_UpdateAreaRoutingCache
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
aas_routingcache_t *AAS_GetAreaRoutingCache(int clusternum, int areanum, int travelflags)
{
int clusterareanum;
aas_routingcache_t *cache, *clustercache;
//number of the area in the cluster
clusterareanum = AAS_ClusterAreaNum(clusternum, areanum);
//pointer to the cache for the area in the cluster
clustercache = aasworld.clusterareacache[clusternum][clusterareanum];
//find the cache without undesired travel flags
for (cache = clustercache; cache; cache = cache->next)
{
//if there aren't used any undesired travel types for the cache
if (cache->travelflags == travelflags) break;
} //end for
//if there was no cache
if (!cache)
{
cache = AAS_AllocRoutingCache(aasworld.clusters[clusternum].numreachabilityareas);
cache->cluster = clusternum;
cache->areanum = areanum;
VectorCopy(aasworld.areas[areanum].center, cache->origin);
cache->starttraveltime = 1;
cache->travelflags = travelflags;
cache->prev = NULL;
cache->next = clustercache;
if (clustercache) clustercache->prev = cache;
aasworld.clusterareacache[clusternum][clusterareanum] = cache;
AAS_UpdateAreaRoutingCache(cache);
} //end if
else
{
AAS_UnlinkCache(cache);
} //end else
//the cache has been accessed
cache->time = AAS_RoutingTime();
cache->type = CACHETYPE_AREA;
AAS_LinkCache(cache);
return cache;
} //end of the function AAS_GetAreaRoutingCache
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_UpdatePortalRoutingCache(aas_routingcache_t *portalcache)
{
int i, portalnum, clusterareanum, clusternum;
unsigned short int t;
aas_portal_t *portal;
aas_cluster_t *cluster;
aas_routingcache_t *cache;
aas_routingupdate_t *updateliststart, *updatelistend, *curupdate, *nextupdate;
#ifdef ROUTING_DEBUG
numportalcacheupdates++;
#endif //ROUTING_DEBUG
//clear the routing update fields
// Com_Memset(aasworld.portalupdate, 0, (aasworld.numportals+1) * sizeof(aas_routingupdate_t));
//
curupdate = &aasworld.portalupdate[aasworld.numportals];
curupdate->cluster = portalcache->cluster;
curupdate->areanum = portalcache->areanum;
curupdate->tmptraveltime = portalcache->starttraveltime;
//if the start area is a cluster portal, store the travel time for that portal
clusternum = aasworld.areasettings[portalcache->areanum].cluster;
if (clusternum < 0)
{
portalcache->traveltimes[-clusternum] = portalcache->starttraveltime;
} //end if
//put the area to start with in the current read list
curupdate->next = NULL;
curupdate->prev = NULL;
updateliststart = curupdate;
updatelistend = curupdate;
//while there are updates in the current list
while (updateliststart)
{
curupdate = updateliststart;
//remove the current update from the list
if (curupdate->next) curupdate->next->prev = NULL;
else updatelistend = NULL;
updateliststart = curupdate->next;
//current update is removed from the list
curupdate->inlist = qfalse;
//
cluster = &aasworld.clusters[curupdate->cluster];
//
cache = AAS_GetAreaRoutingCache(curupdate->cluster,
curupdate->areanum, portalcache->travelflags);
//take all portals of the cluster
for (i = 0; i < cluster->numportals; i++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -