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

be_aas_entity.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_entity.c
00025  *
00026  * desc:        AAS entities
00027  *
00028  * $Archive: /MissionPack/code/botlib/be_aas_entity.c $
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 //FIXME: these might change
00049 enum {
00050     ET_GENERAL,
00051     ET_PLAYER,
00052     ET_ITEM,
00053     ET_MISSILE,
00054     ET_MOVER
00055 };
00056 
00057 //===========================================================================
00058 //
00059 // Parameter:               -
00060 // Returns:                 -
00061 // Changes Globals:     -
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     } //end if
00074 
00075     ent = &aasworld.entities[entnum];
00076 
00077     if (!state) {
00078         //unlink the entity
00079         AAS_UnlinkFromAreas(ent->areas);
00080         //unlink the entity from the BSP leaves
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     //number of the entity
00107     ent->i.number = entnum;
00108     //updated so set valid flag
00109     ent->i.valid = qtrue;
00110     //link everything the first frame
00111     if (aasworld.numframes == 1) relink = qtrue;
00112     else relink = qfalse;
00113     //
00114     if (ent->i.solid == SOLID_BSP)
00115     {
00116         //if the angles of the model changed
00117         if (!VectorCompare(state->angles, ent->i.angles))
00118         {
00119             VectorCopy(state->angles, ent->i.angles);
00120             relink = qtrue;
00121         } //end if
00122         //get the mins and maxs of the model
00123         //FIXME: rotate mins and maxs
00124         AAS_BSPModelMinsMaxsOrigin(ent->i.modelindex, ent->i.angles, ent->i.mins, ent->i.maxs, NULL);
00125     } //end if
00126     else if (ent->i.solid == SOLID_BBOX)
00127     {
00128         //if the bounding box size changed
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         } //end if
00136         VectorCopy(state->angles, ent->i.angles);
00137     } //end if
00138     //if the origin changed
00139     if (!VectorCompare(state->origin, ent->i.origin))
00140     {
00141         VectorCopy(state->origin, ent->i.origin);
00142         relink = qtrue;
00143     } //end if
00144     //if the entity should be relinked
00145     if (relink)
00146     {
00147         //don't link the world model
00148         if (entnum != ENTITYNUM_WORLD)
00149         {
00150             //absolute mins and maxs
00151             VectorAdd(ent->i.mins, ent->i.origin, absmins);
00152             VectorAdd(ent->i.maxs, ent->i.origin, absmaxs);
00153             //unlink the entity
00154             AAS_UnlinkFromAreas(ent->areas);
00155             //relink the entity to the AAS areas (use the larges bbox)
00156             ent->areas = AAS_LinkEntityClientBBox(absmins, absmaxs, entnum, PRESENCE_NORMAL);
00157             //unlink the entity from the BSP leaves
00158             AAS_UnlinkFromBSPLeaves(ent->leaves);
00159             //link the entity to the world BSP tree
00160             ent->leaves = AAS_BSPLinkEntity(absmins, absmaxs, entnum, 0);
00161         } //end if
00162     } //end if
00163     return BLERR_NOERROR;
00164 } //end of the function AAS_UpdateEntity
00165 //===========================================================================
00166 //
00167 // Parameter:           -
00168 // Returns:             -
00169 // Changes Globals:     -
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     } //end if
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     } //end if
00186 
00187     Com_Memcpy(info, &aasworld.entities[entnum].i, sizeof(aas_entityinfo_t));
00188 } //end of the function AAS_EntityInfo
00189 //===========================================================================
00190 //
00191 // Parameter:               -
00192 // Returns:                 -
00193 // Changes Globals:     -
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     } //end if
00203 
00204     VectorCopy(aasworld.entities[entnum].i.origin, origin);
00205 } //end of the function AAS_EntityOrigin
00206 //===========================================================================
00207 //
00208 // Parameter:               -
00209 // Returns:                 -
00210 // Changes Globals:     -
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     } //end if
00219     return aasworld.entities[entnum].i.modelindex;
00220 } //end of the function AAS_EntityModelindex
00221 //===========================================================================
00222 //
00223 // Parameter:               -
00224 // Returns:                 -
00225 // Changes Globals:     -
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     } //end if
00236     return aasworld.entities[entnum].i.type;
00237 } //end of the AAS_EntityType
00238 //===========================================================================
00239 //
00240 // Parameter:               -
00241 // Returns:                 -
00242 // Changes Globals:     -
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     } //end if
00253     return aasworld.entities[entnum].i.modelindex;
00254 } //end of the function AAS_EntityModelNum
00255 //===========================================================================
00256 //
00257 // Parameter:               -
00258 // Returns:                 -
00259 // Changes Globals:     -
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             } //end if
00276         } //end if
00277     } //end for
00278     return qfalse;
00279 } //end of the function AAS_OriginOfMoverWithModelNum
00280 //===========================================================================
00281 //
00282 // Parameter:               -
00283 // Returns:                 -
00284 // Changes Globals:     -
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     } //end if
00297 
00298     ent = &aasworld.entities[entnum];
00299     VectorCopy(ent->i.mins, mins);
00300     VectorCopy(ent->i.maxs, maxs);
00301 } //end of the function AAS_EntitySize
00302 //===========================================================================
00303 //
00304 // Parameter:               -
00305 // Returns:                 -
00306 // Changes Globals:     -
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 } //end of the function AAS_EntityBSPData
00320 //===========================================================================
00321 //
00322 // Parameter:               -
00323 // Returns:                 -
00324 // Changes Globals:     -
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     } //end for
00334 } //end of the function AAS_ResetEntityLinks
00335 //===========================================================================
00336 //
00337 // Parameter:               -
00338 // Returns:                 -
00339 // Changes Globals:     -
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     } //end for
00349 } //end of the function AAS_InvalidateEntities
00350 //===========================================================================
00351 //
00352 // Parameter:               -
00353 // Returns:                 -
00354 // Changes Globals:     -
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         } //end for
00371     } //end for
00372 } //end of the function AAS_UnlinkInvalidEntities
00373 //===========================================================================
00374 //
00375 // Parameter:               -
00376 // Returns:                 -
00377 // Changes Globals:     -
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                 } //end if
00403             } //end if
00404         } //end if
00405     } //end for
00406     return bestentnum;
00407 } //end of the function AAS_NearestEntity
00408 //===========================================================================
00409 //
00410 // Parameter:               -
00411 // Returns:                 -
00412 // Changes Globals:     -
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 } //end of the function AAS_BestReachableEntityArea
00421 //===========================================================================
00422 //
00423 // Parameter:           -
00424 // Returns:             -
00425 // Changes Globals:     -
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     } //end while
00436     return 0;
00437 } //end of the function AAS_NextEntity

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