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_script.h"
00035 #include "l_precomp.h"
00036 #include "l_struct.h"
00037 #include "l_utils.h"
00038 #include "l_log.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 MASK_SOLID CONTENTS_PLAYERCLIP
00047
00048
00049 enum {
00050 ET_GENERAL,
00051 ET_PLAYER,
00052 ET_ITEM,
00053 ET_MISSILE,
00054 ET_MOVER
00055 };
00056
00057
00058
00059
00060
00061
00062
00063 int AAS_UpdateEntity(int entnum, bot_entitystate_t *state)
00064 {
00065 int relink;
00066 aas_entity_t *ent;
00067 vec3_t absmins, absmaxs;
00068
00069 if (!aasworld.loaded)
00070 {
00071 botimport.Print(PRT_MESSAGE, "AAS_UpdateEntity: not loaded\n");
00072 return BLERR_NOAASFILE;
00073 }
00074
00075 ent = &aasworld.entities[entnum];
00076
00077 if (!state) {
00078
00079 AAS_UnlinkFromAreas(ent->areas);
00080
00081 AAS_UnlinkFromBSPLeaves(ent->leaves);
00082
00083 ent->areas = NULL;
00084
00085 ent->leaves = NULL;
00086 return BLERR_NOERROR;
00087 }
00088
00089 ent->i.update_time = AAS_Time() - ent->i.ltime;
00090 ent->i.type = state->type;
00091 ent->i.flags = state->flags;
00092 ent->i.ltime = AAS_Time();
00093 VectorCopy(ent->i.origin, ent->i.lastvisorigin);
00094 VectorCopy(state->old_origin, ent->i.old_origin);
00095 ent->i.solid = state->solid;
00096 ent->i.groundent = state->groundent;
00097 ent->i.modelindex = state->modelindex;
00098 ent->i.modelindex2 = state->modelindex2;
00099 ent->i.frame = state->frame;
00100 ent->i.event = state->event;
00101 ent->i.eventParm = state->eventParm;
00102 ent->i.powerups = state->powerups;
00103 ent->i.weapon = state->weapon;
00104 ent->i.legsAnim = state->legsAnim;
00105 ent->i.torsoAnim = state->torsoAnim;
00106
00107 ent->i.number = entnum;
00108
00109 ent->i.valid = qtrue;
00110
00111 if (aasworld.numframes == 1) relink = qtrue;
00112 else relink = qfalse;
00113
00114 if (ent->i.solid == SOLID_BSP)
00115 {
00116
00117 if (!VectorCompare(state->angles, ent->i.angles))
00118 {
00119 VectorCopy(state->angles, ent->i.angles);
00120 relink = qtrue;
00121 }
00122
00123
00124 AAS_BSPModelMinsMaxsOrigin(ent->i.modelindex, ent->i.angles, ent->i.mins, ent->i.maxs, NULL);
00125 }
00126 else if (ent->i.solid == SOLID_BBOX)
00127 {
00128
00129 if (!VectorCompare(state->mins, ent->i.mins) ||
00130 !VectorCompare(state->maxs, ent->i.maxs))
00131 {
00132 VectorCopy(state->mins, ent->i.mins);
00133 VectorCopy(state->maxs, ent->i.maxs);
00134 relink = qtrue;
00135 }
00136 VectorCopy(state->angles, ent->i.angles);
00137 }
00138
00139 if (!VectorCompare(state->origin, ent->i.origin))
00140 {
00141 VectorCopy(state->origin, ent->i.origin);
00142 relink = qtrue;
00143 }
00144
00145 if (relink)
00146 {
00147
00148 if (entnum != ENTITYNUM_WORLD)
00149 {
00150
00151 VectorAdd(ent->i.mins, ent->i.origin, absmins);
00152 VectorAdd(ent->i.maxs, ent->i.origin, absmaxs);
00153
00154 AAS_UnlinkFromAreas(ent->areas);
00155
00156 ent->areas = AAS_LinkEntityClientBBox(absmins, absmaxs, entnum, PRESENCE_NORMAL);
00157
00158 AAS_UnlinkFromBSPLeaves(ent->leaves);
00159
00160 ent->leaves = AAS_BSPLinkEntity(absmins, absmaxs, entnum, 0);
00161 }
00162 }
00163 return BLERR_NOERROR;
00164 }
00165
00166
00167
00168
00169
00170
00171 void AAS_EntityInfo(int entnum, aas_entityinfo_t *info)
00172 {
00173 if (!aasworld.initialized)
00174 {
00175 botimport.Print(PRT_FATAL, "AAS_EntityInfo: aasworld not initialized\n");
00176 Com_Memset(info, 0, sizeof(aas_entityinfo_t));
00177 return;
00178 }
00179
00180 if (entnum < 0 || entnum >= aasworld.maxentities)
00181 {
00182 botimport.Print(PRT_FATAL, "AAS_EntityInfo: entnum %d out of range\n", entnum);
00183 Com_Memset(info, 0, sizeof(aas_entityinfo_t));
00184 return;
00185 }
00186
00187 Com_Memcpy(info, &aasworld.entities[entnum].i, sizeof(aas_entityinfo_t));
00188 }
00189
00190
00191
00192
00193
00194
00195 void AAS_EntityOrigin(int entnum, vec3_t origin)
00196 {
00197 if (entnum < 0 || entnum >= aasworld.maxentities)
00198 {
00199 botimport.Print(PRT_FATAL, "AAS_EntityOrigin: entnum %d out of range\n", entnum);
00200 VectorClear(origin);
00201 return;
00202 }
00203
00204 VectorCopy(aasworld.entities[entnum].i.origin, origin);
00205 }
00206
00207
00208
00209
00210
00211
00212 int AAS_EntityModelindex(int entnum)
00213 {
00214 if (entnum < 0 || entnum >= aasworld.maxentities)
00215 {
00216 botimport.Print(PRT_FATAL, "AAS_EntityModelindex: entnum %d out of range\n", entnum);
00217 return 0;
00218 }
00219 return aasworld.entities[entnum].i.modelindex;
00220 }
00221
00222
00223
00224
00225
00226
00227 int AAS_EntityType(int entnum)
00228 {
00229 if (!aasworld.initialized) return 0;
00230
00231 if (entnum < 0 || entnum >= aasworld.maxentities)
00232 {
00233 botimport.Print(PRT_FATAL, "AAS_EntityType: entnum %d out of range\n", entnum);
00234 return 0;
00235 }
00236 return aasworld.entities[entnum].i.type;
00237 }
00238
00239
00240
00241
00242
00243
00244 int AAS_EntityModelNum(int entnum)
00245 {
00246 if (!aasworld.initialized) return 0;
00247
00248 if (entnum < 0 || entnum >= aasworld.maxentities)
00249 {
00250 botimport.Print(PRT_FATAL, "AAS_EntityModelNum: entnum %d out of range\n", entnum);
00251 return 0;
00252 }
00253 return aasworld.entities[entnum].i.modelindex;
00254 }
00255
00256
00257
00258
00259
00260
00261 int AAS_OriginOfMoverWithModelNum(int modelnum, vec3_t origin)
00262 {
00263 int i;
00264 aas_entity_t *ent;
00265
00266 for (i = 0; i < aasworld.maxentities; i++)
00267 {
00268 ent = &aasworld.entities[i];
00269 if (ent->i.type == ET_MOVER)
00270 {
00271 if (ent->i.modelindex == modelnum)
00272 {
00273 VectorCopy(ent->i.origin, origin);
00274 return qtrue;
00275 }
00276 }
00277 }
00278 return qfalse;
00279 }
00280
00281
00282
00283
00284
00285
00286 void AAS_EntitySize(int entnum, vec3_t mins, vec3_t maxs)
00287 {
00288 aas_entity_t *ent;
00289
00290 if (!aasworld.initialized) return;
00291
00292 if (entnum < 0 || entnum >= aasworld.maxentities)
00293 {
00294 botimport.Print(PRT_FATAL, "AAS_EntitySize: entnum %d out of range\n", entnum);
00295 return;
00296 }
00297
00298 ent = &aasworld.entities[entnum];
00299 VectorCopy(ent->i.mins, mins);
00300 VectorCopy(ent->i.maxs, maxs);
00301 }
00302
00303
00304
00305
00306
00307
00308 void AAS_EntityBSPData(int entnum, bsp_entdata_t *entdata)
00309 {
00310 aas_entity_t *ent;
00311
00312 ent = &aasworld.entities[entnum];
00313 VectorCopy(ent->i.origin, entdata->origin);
00314 VectorCopy(ent->i.angles, entdata->angles);
00315 VectorAdd(ent->i.origin, ent->i.mins, entdata->absmins);
00316 VectorAdd(ent->i.origin, ent->i.maxs, entdata->absmaxs);
00317 entdata->solid = ent->i.solid;
00318 entdata->modelnum = ent->i.modelindex - 1;
00319 }
00320
00321
00322
00323
00324
00325
00326 void AAS_ResetEntityLinks(void)
00327 {
00328 int i;
00329 for (i = 0; i < aasworld.maxentities; i++)
00330 {
00331 aasworld.entities[i].areas = NULL;
00332 aasworld.entities[i].leaves = NULL;
00333 }
00334 }
00335
00336
00337
00338
00339
00340
00341 void AAS_InvalidateEntities(void)
00342 {
00343 int i;
00344 for (i = 0; i < aasworld.maxentities; i++)
00345 {
00346 aasworld.entities[i].i.valid = qfalse;
00347 aasworld.entities[i].i.number = i;
00348 }
00349 }
00350
00351
00352
00353
00354
00355
00356 void AAS_UnlinkInvalidEntities(void)
00357 {
00358 int i;
00359 aas_entity_t *ent;
00360
00361 for (i = 0; i < aasworld.maxentities; i++)
00362 {
00363 ent = &aasworld.entities[i];
00364 if (!ent->i.valid)
00365 {
00366 AAS_UnlinkFromAreas( ent->areas );
00367 ent->areas = NULL;
00368 AAS_UnlinkFromBSPLeaves( ent->leaves );
00369 ent->leaves = NULL;
00370 }
00371 }
00372 }
00373
00374
00375
00376
00377
00378
00379 int AAS_NearestEntity(vec3_t origin, int modelindex)
00380 {
00381 int i, bestentnum;
00382 float dist, bestdist;
00383 aas_entity_t *ent;
00384 vec3_t dir;
00385
00386 bestentnum = 0;
00387 bestdist = 99999;
00388 for (i = 0; i < aasworld.maxentities; i++)
00389 {
00390 ent = &aasworld.entities[i];
00391 if (ent->i.modelindex != modelindex) continue;
00392 VectorSubtract(ent->i.origin, origin, dir);
00393 if (abs(dir[0]) < 40)
00394 {
00395 if (abs(dir[1]) < 40)
00396 {
00397 dist = VectorLength(dir);
00398 if (dist < bestdist)
00399 {
00400 bestdist = dist;
00401 bestentnum = i;
00402 }
00403 }
00404 }
00405 }
00406 return bestentnum;
00407 }
00408
00409
00410
00411
00412
00413
00414 int AAS_BestReachableEntityArea(int entnum)
00415 {
00416 aas_entity_t *ent;
00417
00418 ent = &aasworld.entities[entnum];
00419 return AAS_BestReachableLinkArea(ent->areas);
00420 }
00421
00422
00423
00424
00425
00426
00427 int AAS_NextEntity(int entnum)
00428 {
00429 if (!aasworld.loaded) return 0;
00430
00431 if (entnum < 0) entnum = -1;
00432 while(++entnum < aasworld.maxentities)
00433 {
00434 if (aasworld.entities[entnum].i.valid) return entnum;
00435 }
00436 return 0;
00437 }