aas_rt_route_t *AAS_RT_GetRoute( int srcnum, vec3_t origin, int destnum ) { #define GETROUTE_NUMROUTES 64 static aas_rt_route_t routes[GETROUTE_NUMROUTES]; // cycle through these, so we don't overlap static int routeIndex = 0; aas_rt_route_t *thisroute; int reach, traveltime; aas_rt_t *rt; static int tfl = TFL_DEFAULT & ~( TFL_JUMPPAD | TFL_ROCKETJUMP | TFL_BFGJUMP | TFL_GRAPPLEHOOK | TFL_DOUBLEJUMP | TFL_RAMPJUMP | TFL_STRAFEJUMP | TFL_LAVA ); //----(SA) modified since slime is no longer deadly // static int tfl = TFL_DEFAULT & ~(TFL_JUMPPAD|TFL_ROCKETJUMP|TFL_BFGJUMP|TFL_GRAPPLEHOOK|TFL_DOUBLEJUMP|TFL_RAMPJUMP|TFL_STRAFEJUMP|TFL_SLIME|TFL_LAVA); if ( !( rt = aasworld->routetable ) ) { // no route table present return NULL; } if ( disable_routetable ) { return NULL; } if ( ++routeIndex >= GETROUTE_NUMROUTES ) { routeIndex = 0; } thisroute = &routes[routeIndex]; if ( AAS_AreaRouteToGoalArea( srcnum, origin, destnum, tfl, &traveltime, &reach ) ) { thisroute->reachable_index = reach; thisroute->travel_time = traveltime; return thisroute; } else { return NULL; } }
void AAS_RT_CalcTravelTimesToGoalArea( int goalarea ) { int i; // TTimo: unused // static int tfl = TFL_DEFAULT & ~(TFL_JUMPPAD|TFL_ROCKETJUMP|TFL_BFGJUMP|TFL_GRAPPLEHOOK|TFL_DOUBLEJUMP|TFL_RAMPJUMP|TFL_STRAFEJUMP|TFL_LAVA); //----(SA) modified since slime is no longer deadly // static int tfl = TFL_DEFAULT & ~(TFL_JUMPPAD|TFL_ROCKETJUMP|TFL_BFGJUMP|TFL_GRAPPLEHOOK|TFL_DOUBLEJUMP|TFL_RAMPJUMP|TFL_STRAFEJUMP|TFL_SLIME|TFL_LAVA); aas_rt_route_t *rt; int reach, travel; for ( i = 0; i < childcount; i++ ) { rt = &routetable[i][-1 + rev_filtered_areas[goalarea]]; if ( AAS_AreaRouteToGoalArea( filtered_areas[i], ( *aasworld ).areas[filtered_areas[i]].center, goalarea, ~RTB_BADTRAVELFLAGS, &travel, &reach ) ) { rt->reachable_index = reach; rt->travel_time = travel; } else { //rt->reachable_index = -1; rt->travel_time = 0; } } }
int AAS_AlternativeRouteGoals(vec3_t start, vec3_t goal, int travelflags, aas_altroutegoal_t *altroutegoals, int maxaltroutegoals, int color) { #ifndef ENABLE_ALTROUTING return 0; #else int i, j, startareanum, goalareanum, bestareanum; int numaltroutegoals, nummidrangeareas; int starttime, goaltime, goaltraveltime; float dist, bestdist; vec3_t mid, dir; int reachnum, time; int a1, a2; /*#ifdef DEBUG int startmillisecs; startmillisecs = Sys_MilliSeconds(); #endif*/ startareanum = AAS_PointAreaNum(start); if (!startareanum) { return 0; } goalareanum = AAS_PointAreaNum(goal); if (!goalareanum) { VectorCopy(goal, dir); dir[2] += 30; goalareanum = AAS_PointAreaNum(dir); if (!goalareanum) { return 0; } } //travel time towards the goal area goaltraveltime = AAS_AreaTravelTimeToGoalArea(startareanum, start, goalareanum, travelflags); //clear the midrange areas memset(midrangeareas, 0, (*aasworld).numareas * sizeof(midrangearea_t)); numaltroutegoals = 0; // nummidrangeareas = 0; // for (i = 1; i < (*aasworld).numareas; i++) { // if (!((*aasworld).areasettings[i].contents & AREACONTENTS_ROUTEPORTAL) && !((*aasworld).areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)) { continue; } //if the area has no reachabilities if (!AAS_AreaReachability(i)) { continue; } //tavel time from the area to the start area starttime = AAS_AreaTravelTimeToGoalArea(startareanum, start, i, travelflags); if (!starttime) { continue; } //if the travel time from the start to the area is greater than the shortest goal travel time if (starttime > 500 + 3.0 * goaltraveltime) { continue; } //travel time from the area to the goal area goaltime = AAS_AreaTravelTimeToGoalArea(i, NULL, goalareanum, travelflags); if (!goaltime) { continue; } //if the travel time from the area to the goal is greater than the shortest goal travel time if (goaltime > 500 + 3.0 * goaltraveltime) { continue; } //this is a mid range area midrangeareas[i].valid = qtrue; midrangeareas[i].starttime = starttime; midrangeareas[i].goaltime = goaltime; Log_Write("%d midrange area %d", nummidrangeareas, i); nummidrangeareas++; } //end for // for (i = 1; i < (*aasworld).numareas; i++) { if (!midrangeareas[i].valid) { continue; } //get the areas in one cluster numclusterareas = 0; AAS_AltRoutingFloodCluster_r(i); //now we've got a cluster with areas through which an alternative route could go //get the 'center' of the cluster VectorClear(mid); for (j = 0; j < numclusterareas; j++) { VectorAdd(mid, (*aasworld).areas[clusterareas[j]].center, mid); } //end for VectorScale(mid, 1.0 / numclusterareas, mid); //get the area closest to the center of the cluster bestdist = 999999; bestareanum = 0; for (j = 0; j < numclusterareas; j++) { VectorSubtract(mid, (*aasworld).areas[clusterareas[j]].center, dir); dist = VectorLength(dir); if (dist < bestdist) { bestdist = dist; bestareanum = clusterareas[j]; } //end if } //end for // make sure the route to the destination isn't in the same direction as the route to the source if (!AAS_AreaRouteToGoalArea(bestareanum, (*aasworld).areawaypoints[bestareanum], goalareanum, travelflags, &time, &reachnum)) { continue; } a1 = (*aasworld).reachability[reachnum].areanum; if (!AAS_AreaRouteToGoalArea(bestareanum, (*aasworld).areawaypoints[bestareanum], startareanum, travelflags, &time, &reachnum)) { continue; } a2 = (*aasworld).reachability[reachnum].areanum; if (a1 == a2) { continue; } //now we've got an area for an alternative route //FIXME: add alternative goal origin VectorCopy((*aasworld).areawaypoints[bestareanum], altroutegoals[numaltroutegoals].origin); altroutegoals[numaltroutegoals].areanum = bestareanum; altroutegoals[numaltroutegoals].starttraveltime = midrangeareas[bestareanum].starttime; altroutegoals[numaltroutegoals].goaltraveltime = midrangeareas[bestareanum].goaltime; altroutegoals[numaltroutegoals].extratraveltime = (midrangeareas[bestareanum].starttime + midrangeareas[bestareanum].goaltime) - goaltraveltime; numaltroutegoals++; // /*#ifdef DEBUG botimport.Print(PRT_MESSAGE, "alternative route goal area %d, numclusterareas = %d\n", bestareanum, numclusterareas); if (color) { AAS_DrawPermanentCross((*aasworld).areas[bestareanum].center, 10, color); } //end if //AAS_ShowArea(bestarea, qtrue); #endif*/ //don't return more than the maximum alternative route goals if (numaltroutegoals >= maxaltroutegoals) { break; } } //end for //botimport.Print(PRT_MESSAGE, "%d alternative route goals\n", numaltroutegoals); #ifdef DEBUG // botimport.Print(PRT_MESSAGE, "alternative route goals in %d msec\n", Sys_MilliSeconds() - startmillisecs); #endif return numaltroutegoals; #endif } //end of the function AAS_AlternativeRouteGoals