Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

be_aas_routealt.c

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 
00023 /*****************************************************************************
00024  * name:        be_aas_routealt.c
00025  *
00026  * desc:        AAS
00027  *
00028  * $Archive: /MissionPack/code/botlib/be_aas_routealt.c $
00029  *
00030  *****************************************************************************/
00031 
00032 #include "../game/q_shared.h"
00033 #include "l_utils.h"
00034 #include "l_memory.h"
00035 #include "l_log.h"
00036 #include "l_script.h"
00037 #include "l_precomp.h"
00038 #include "l_struct.h"
00039 #include "aasfile.h"
00040 #include "../game/botlib.h"
00041 #include "../game/be_aas.h"
00042 #include "be_aas_funcs.h"
00043 #include "be_interface.h"
00044 #include "be_aas_def.h"
00045 
00046 #define ENABLE_ALTROUTING
00047 //#define ALTROUTE_DEBUG
00048 
00049 typedef struct midrangearea_s
00050 {
00051     int valid;
00052     unsigned short starttime;
00053     unsigned short goaltime;
00054 } midrangearea_t;
00055 
00056 midrangearea_t *midrangeareas;
00057 int *clusterareas;
00058 int numclusterareas;
00059 
00060 //===========================================================================
00061 //
00062 // Parameter:               -
00063 // Returns:                 -
00064 // Changes Globals:     -
00065 //===========================================================================
00066 void AAS_AltRoutingFloodCluster_r(int areanum)
00067 {
00068     int i, otherareanum;
00069     aas_area_t *area;
00070     aas_face_t *face;
00071 
00072     //add the current area to the areas of the current cluster
00073     clusterareas[numclusterareas] = areanum;
00074     numclusterareas++;
00075     //remove the area from the mid range areas
00076     midrangeareas[areanum].valid = qfalse;
00077     //flood to other areas through the faces of this area
00078     area = &aasworld.areas[areanum];
00079     for (i = 0; i < area->numfaces; i++)
00080     {
00081         face = &aasworld.faces[abs(aasworld.faceindex[area->firstface + i])];
00082         //get the area at the other side of the face
00083         if (face->frontarea == areanum) otherareanum = face->backarea;
00084         else otherareanum = face->frontarea;
00085         //if there is an area at the other side of this face
00086         if (!otherareanum) continue;
00087         //if the other area is not a midrange area
00088         if (!midrangeareas[otherareanum].valid) continue;
00089         //
00090         AAS_AltRoutingFloodCluster_r(otherareanum);
00091     } //end for
00092 } //end of the function AAS_AltRoutingFloodCluster_r
00093 //===========================================================================
00094 //
00095 // Parameter:               -
00096 // Returns:                 -
00097 // Changes Globals:     -
00098 //===========================================================================
00099 int AAS_AlternativeRouteGoals(vec3_t start, int startareanum, vec3_t goal, int goalareanum, int travelflags,
00100                                          aas_altroutegoal_t *altroutegoals, int maxaltroutegoals,
00101                                          int type)
00102 {
00103 #ifndef ENABLE_ALTROUTING
00104     return 0;
00105 #else
00106     int i, j, bestareanum;
00107     int numaltroutegoals, nummidrangeareas;
00108     int starttime, goaltime, goaltraveltime;
00109     float dist, bestdist;
00110     vec3_t mid, dir;
00111 #ifdef ALTROUTE_DEBUG
00112     int startmillisecs;
00113 
00114     startmillisecs = Sys_MilliSeconds();
00115 #endif
00116 
00117     if (!startareanum || !goalareanum)
00118         return 0;
00119     //travel time towards the goal area
00120     goaltraveltime = AAS_AreaTravelTimeToGoalArea(startareanum, start, goalareanum, travelflags);
00121     //clear the midrange areas
00122     Com_Memset(midrangeareas, 0, aasworld.numareas * sizeof(midrangearea_t));
00123     numaltroutegoals = 0;
00124     //
00125     nummidrangeareas = 0;
00126     //
00127     for (i = 1; i < aasworld.numareas; i++)
00128     {
00129         //
00130         if (!(type & ALTROUTEGOAL_ALL))
00131         {
00132             if (!(type & ALTROUTEGOAL_CLUSTERPORTALS && (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)))
00133             {
00134                 if (!(type & ALTROUTEGOAL_VIEWPORTALS && (aasworld.areasettings[i].contents & AREACONTENTS_VIEWPORTAL)))
00135                 {
00136                     continue;
00137                 } //end if
00138             } //end if
00139         } //end if
00140         //if the area has no reachabilities
00141         if (!AAS_AreaReachability(i)) continue;
00142         //tavel time from the area to the start area
00143         starttime = AAS_AreaTravelTimeToGoalArea(startareanum, start, i, travelflags);
00144         if (!starttime) continue;
00145         //if the travel time from the start to the area is greater than the shortest goal travel time
00146         if (starttime > (float) 1.1 * goaltraveltime) continue;
00147         //travel time from the area to the goal area
00148         goaltime = AAS_AreaTravelTimeToGoalArea(i, NULL, goalareanum, travelflags);
00149         if (!goaltime) continue;
00150         //if the travel time from the area to the goal is greater than the shortest goal travel time
00151         if (goaltime > (float) 0.8 * goaltraveltime) continue;
00152         //this is a mid range area
00153         midrangeareas[i].valid = qtrue;
00154         midrangeareas[i].starttime = starttime;
00155         midrangeareas[i].goaltime = goaltime;
00156         Log_Write("%d midrange area %d", nummidrangeareas, i);
00157         nummidrangeareas++;
00158     } //end for
00159     //
00160     for (i = 1; i < aasworld.numareas; i++)
00161     {
00162         if (!midrangeareas[i].valid) continue;
00163         //get the areas in one cluster
00164         numclusterareas = 0;
00165         AAS_AltRoutingFloodCluster_r(i);
00166         //now we've got a cluster with areas through which an alternative route could go
00167         //get the 'center' of the cluster
00168         VectorClear(mid);
00169         for (j = 0; j < numclusterareas; j++)
00170         {
00171             VectorAdd(mid, aasworld.areas[clusterareas[j]].center, mid);
00172         } //end for
00173         VectorScale(mid, 1.0 / numclusterareas, mid);
00174         //get the area closest to the center of the cluster
00175         bestdist = 999999;
00176         bestareanum = 0;
00177         for (j = 0; j < numclusterareas; j++)
00178         {
00179             VectorSubtract(mid, aasworld.areas[clusterareas[j]].center, dir);
00180             dist = VectorLength(dir);
00181             if (dist < bestdist)
00182             {
00183                 bestdist = dist;
00184                 bestareanum = clusterareas[j];
00185             } //end if
00186         } //end for
00187         //now we've got an area for an alternative route
00188         //FIXME: add alternative goal origin
00189         VectorCopy(aasworld.areas[bestareanum].center, altroutegoals[numaltroutegoals].origin);
00190         altroutegoals[numaltroutegoals].areanum = bestareanum;
00191         altroutegoals[numaltroutegoals].starttraveltime = midrangeareas[bestareanum].starttime;
00192         altroutegoals[numaltroutegoals].goaltraveltime = midrangeareas[bestareanum].goaltime;
00193         altroutegoals[numaltroutegoals].extratraveltime =
00194                     (midrangeareas[bestareanum].starttime + midrangeareas[bestareanum].goaltime) -
00195                                 goaltraveltime;
00196         numaltroutegoals++;
00197         //
00198 #ifdef ALTROUTE_DEBUG
00199         AAS_ShowAreaPolygons(bestareanum, 1, qtrue);
00200 #endif
00201         //don't return more than the maximum alternative route goals
00202         if (numaltroutegoals >= maxaltroutegoals) break;
00203     } //end for
00204 #ifdef ALTROUTE_DEBUG
00205     botimport.Print(PRT_MESSAGE, "alternative route goals in %d msec\n", Sys_MilliSeconds() - startmillisecs);
00206 #endif
00207     return numaltroutegoals;
00208 #endif
00209 } //end of the function AAS_AlternativeRouteGoals
00210 //===========================================================================
00211 //
00212 // Parameter:               -
00213 // Returns:                 -
00214 // Changes Globals:     -
00215 //===========================================================================
00216 void AAS_InitAlternativeRouting(void)
00217 {
00218 #ifdef ENABLE_ALTROUTING
00219     if (midrangeareas) FreeMemory(midrangeareas);
00220     midrangeareas = (midrangearea_t *) GetMemory(aasworld.numareas * sizeof(midrangearea_t));
00221     if (clusterareas) FreeMemory(clusterareas);
00222     clusterareas = (int *) GetMemory(aasworld.numareas * sizeof(int));
00223 #endif
00224 } //end of the function AAS_InitAlternativeRouting
00225 //===========================================================================
00226 //
00227 // Parameter:               -
00228 // Returns:                 -
00229 // Changes Globals:     -
00230 //===========================================================================
00231 void AAS_ShutdownAlternativeRouting(void)
00232 {
00233 #ifdef ENABLE_ALTROUTING
00234     if (midrangeareas) FreeMemory(midrangeareas);
00235     midrangeareas = NULL;
00236     if (clusterareas) FreeMemory(clusterareas);
00237     clusterareas = NULL;
00238     numclusterareas = 0;
00239 #endif
00240 } //end of the function AAS_ShutdownAlternativeRouting

Generated on Thu Aug 25 12:37:10 2005 for Quake III Arena by  doxygen 1.3.9.1