00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "../game/q_shared.h"
00033 #include "l_memory.h"
00034 #include "l_libvar.h"
00035 #include "l_utils.h"
00036 #include "l_script.h"
00037 #include "l_precomp.h"
00038 #include "l_struct.h"
00039 #include "l_log.h"
00040 #include "aasfile.h"
00041 #include "../game/botlib.h"
00042 #include "../game/be_aas.h"
00043 #include "be_aas_funcs.h"
00044 #include "be_interface.h"
00045 #include "be_aas_def.h"
00046
00047 aas_t aasworld;
00048
00049 libvar_t *saveroutingcache;
00050
00051
00052
00053
00054
00055
00056
00057 void QDECL AAS_Error(char *fmt, ...)
00058 {
00059 char str[1024];
00060 va_list arglist;
00061
00062 va_start(arglist, fmt);
00063 vsprintf(str, fmt, arglist);
00064 va_end(arglist);
00065 botimport.Print(PRT_FATAL, str);
00066 }
00067
00068
00069
00070
00071
00072
00073 char *AAS_StringFromIndex(char *indexname, char *stringindex[], int numindexes, int index)
00074 {
00075 if (!aasworld.indexessetup)
00076 {
00077 botimport.Print(PRT_ERROR, "%s: index %d not setup\n", indexname, index);
00078 return "";
00079 }
00080 if (index < 0 || index >= numindexes)
00081 {
00082 botimport.Print(PRT_ERROR, "%s: index %d out of range\n", indexname, index);
00083 return "";
00084 }
00085 if (!stringindex[index])
00086 {
00087 if (index)
00088 {
00089 botimport.Print(PRT_ERROR, "%s: reference to unused index %d\n", indexname, index);
00090 }
00091 return "";
00092 }
00093 return stringindex[index];
00094 }
00095
00096
00097
00098
00099
00100
00101 int AAS_IndexFromString(char *indexname, char *stringindex[], int numindexes, char *string)
00102 {
00103 int i;
00104 if (!aasworld.indexessetup)
00105 {
00106 botimport.Print(PRT_ERROR, "%s: index not setup \"%s\"\n", indexname, string);
00107 return 0;
00108 }
00109 for (i = 0; i < numindexes; i++)
00110 {
00111 if (!stringindex[i]) continue;
00112 if (!Q_stricmp(stringindex[i], string)) return i;
00113 }
00114 return 0;
00115 }
00116
00117
00118
00119
00120
00121
00122 char *AAS_ModelFromIndex(int index)
00123 {
00124 return AAS_StringFromIndex("ModelFromIndex", &aasworld.configstrings[CS_MODELS], MAX_MODELS, index);
00125 }
00126
00127
00128
00129
00130
00131
00132 int AAS_IndexFromModel(char *modelname)
00133 {
00134 return AAS_IndexFromString("IndexFromModel", &aasworld.configstrings[CS_MODELS], MAX_MODELS, modelname);
00135 }
00136
00137
00138
00139
00140
00141
00142 void AAS_UpdateStringIndexes(int numconfigstrings, char *configstrings[])
00143 {
00144 int i;
00145
00146 for (i = 0; i < numconfigstrings; i++)
00147 {
00148 if (configstrings[i])
00149 {
00150
00151 aasworld.configstrings[i] = (char *) GetMemory(strlen(configstrings[i]) + 1);
00152 strcpy(aasworld.configstrings[i], configstrings[i]);
00153 }
00154 }
00155 aasworld.indexessetup = qtrue;
00156 }
00157
00158
00159
00160
00161
00162
00163 int AAS_Loaded(void)
00164 {
00165 return aasworld.loaded;
00166 }
00167
00168
00169
00170
00171
00172
00173 int AAS_Initialized(void)
00174 {
00175 return aasworld.initialized;
00176 }
00177
00178
00179
00180
00181
00182
00183 void AAS_SetInitialized(void)
00184 {
00185 aasworld.initialized = qtrue;
00186 botimport.Print(PRT_MESSAGE, "AAS initialized.\n");
00187 #ifdef DEBUG
00188
00189
00190
00191
00192 #endif
00193 }
00194
00195
00196
00197
00198
00199
00200 void AAS_ContinueInit(float time)
00201 {
00202
00203 if (!aasworld.loaded) return;
00204
00205 if (aasworld.initialized) return;
00206
00207 if (AAS_ContinueInitReachability(time)) return;
00208
00209 AAS_InitClustering();
00210
00211
00212 if (aasworld.savefile || ((int)LibVarGetValue("forcewrite")))
00213 {
00214
00215 if ((int)LibVarValue("aasoptimize", "0")) AAS_Optimize();
00216
00217 if (AAS_WriteAASFile(aasworld.filename))
00218 {
00219 botimport.Print(PRT_MESSAGE, "%s written succesfully\n", aasworld.filename);
00220 }
00221 else
00222 {
00223 botimport.Print(PRT_ERROR, "couldn't write %s\n", aasworld.filename);
00224 }
00225 }
00226
00227 AAS_InitRouting();
00228
00229 AAS_SetInitialized();
00230 }
00231
00232
00233
00234
00235
00236
00237
00238 int AAS_StartFrame(float time)
00239 {
00240 aasworld.time = time;
00241
00242 AAS_UnlinkInvalidEntities();
00243
00244 AAS_InvalidateEntities();
00245
00246 AAS_ContinueInit(time);
00247
00248 aasworld.frameroutingupdates = 0;
00249
00250 if (bot_developer)
00251 {
00252 if (LibVarGetValue("showcacheupdates"))
00253 {
00254 AAS_RoutingInfo();
00255 LibVarSet("showcacheupdates", "0");
00256 }
00257 if (LibVarGetValue("showmemoryusage"))
00258 {
00259 PrintUsedMemorySize();
00260 LibVarSet("showmemoryusage", "0");
00261 }
00262 if (LibVarGetValue("memorydump"))
00263 {
00264 PrintMemoryLabels();
00265 LibVarSet("memorydump", "0");
00266 }
00267 }
00268
00269 if (saveroutingcache->value)
00270 {
00271 AAS_WriteRouteCache();
00272 LibVarSet("saveroutingcache", "0");
00273 }
00274
00275 aasworld.numframes++;
00276 return BLERR_NOERROR;
00277 }
00278
00279
00280
00281
00282
00283
00284 float AAS_Time(void)
00285 {
00286 return aasworld.time;
00287 }
00288
00289
00290
00291
00292
00293
00294 void AAS_ProjectPointOntoVector( vec3_t point, vec3_t vStart, vec3_t vEnd, vec3_t vProj )
00295 {
00296 vec3_t pVec, vec;
00297
00298 VectorSubtract( point, vStart, pVec );
00299 VectorSubtract( vEnd, vStart, vec );
00300 VectorNormalize( vec );
00301
00302 VectorMA( vStart, DotProduct( pVec, vec ), vec, vProj );
00303 }
00304
00305
00306
00307
00308
00309
00310 int AAS_LoadFiles(const char *mapname)
00311 {
00312 int errnum;
00313 char aasfile[MAX_PATH];
00314
00315
00316 strcpy(aasworld.mapname, mapname);
00317
00318
00319
00320 AAS_ResetEntityLinks();
00321
00322 AAS_LoadBSPFile();
00323
00324
00325 Com_sprintf(aasfile, MAX_PATH, "maps/%s.aas", mapname);
00326 errnum = AAS_LoadAASFile(aasfile);
00327 if (errnum != BLERR_NOERROR)
00328 return errnum;
00329
00330 botimport.Print(PRT_MESSAGE, "loaded %s\n", aasfile);
00331 strncpy(aasworld.filename, aasfile, MAX_PATH);
00332 return BLERR_NOERROR;
00333 }
00334
00335
00336
00337
00338
00339
00340
00341 int AAS_LoadMap(const char *mapname)
00342 {
00343 int errnum;
00344
00345
00346 if (!mapname)
00347 {
00348 return 0;
00349 }
00350
00351 aasworld.initialized = qfalse;
00352
00353
00354
00355 AAS_FreeRoutingCaches();
00356
00357 errnum = AAS_LoadFiles(mapname);
00358 if (errnum != BLERR_NOERROR)
00359 {
00360 aasworld.loaded = qfalse;
00361 return errnum;
00362 }
00363
00364 AAS_InitSettings();
00365
00366 AAS_InitAASLinkHeap();
00367
00368 AAS_InitAASLinkedEntities();
00369
00370 AAS_InitReachability();
00371
00372 AAS_InitAlternativeRouting();
00373
00374 return 0;
00375 }
00376
00377
00378
00379
00380
00381
00382
00383 int AAS_Setup(void)
00384 {
00385 aasworld.maxclients = (int) LibVarValue("maxclients", "128");
00386 aasworld.maxentities = (int) LibVarValue("maxentities", "1024");
00387
00388 saveroutingcache = LibVar("saveroutingcache", "0");
00389
00390 if (aasworld.entities) FreeMemory(aasworld.entities);
00391 aasworld.entities = (aas_entity_t *) GetClearedHunkMemory(aasworld.maxentities * sizeof(aas_entity_t));
00392
00393 AAS_InvalidateEntities();
00394
00395
00396
00397 aasworld.numframes = 0;
00398 return BLERR_NOERROR;
00399 }
00400
00401
00402
00403
00404
00405
00406 void AAS_Shutdown(void)
00407 {
00408 AAS_ShutdownAlternativeRouting();
00409
00410 AAS_DumpBSPData();
00411
00412 AAS_FreeRoutingCaches();
00413
00414 AAS_FreeAASLinkHeap();
00415
00416 AAS_FreeAASLinkedEntities();
00417
00418 AAS_DumpAASData();
00419
00420 if (aasworld.entities) FreeMemory(aasworld.entities);
00421
00422 Com_Memset(&aasworld, 0, sizeof(aas_t));
00423
00424 aasworld.initialized = qfalse;
00425
00426
00427
00428 botimport.Print(PRT_MESSAGE, "AAS shutdown.\n");
00429 }