void BotUpdateEntityItems( void ) { int ent, i, modelindex; vec3_t dir; levelitem_t *li, *nextli; aas_entityinfo_t entinfo; itemconfig_t *ic; //timeout current entity items if necessary for ( li = levelitems; li; li = nextli ) { nextli = li->next; //if it is a item that will time out if ( li->timeout ) { //timeout the item if ( li->timeout < AAS_Time() ) { RemoveLevelItemFromList( li ); FreeLevelItem( li ); } //end if } //end if } //end for //find new entity items ic = itemconfig; if ( !itemconfig ) { return; } // for ( ent = AAS_NextEntity( 0 ); ent; ent = AAS_NextEntity( ent ) ) { if ( AAS_EntityType( ent ) != ET_ITEM ) { continue; } //get the model index of the entity modelindex = AAS_EntityModelindex( ent ); // if ( !modelindex ) { continue; } //get info about the entity AAS_EntityInfo( ent, &entinfo ); //FIXME: don't do this //skip all floating items for now if ( entinfo.groundent != ENTITYNUM_WORLD ) { continue; } //if the entity is still moving if ( entinfo.origin[0] != entinfo.lastvisorigin[0] || entinfo.origin[1] != entinfo.lastvisorigin[1] || entinfo.origin[2] != entinfo.lastvisorigin[2] ) { continue; } //check if the level item isn't already stored for ( li = levelitems; li; li = li->next ) { //if the model of the level item and the entity are different if ( ic->iteminfo[li->iteminfo].modelindex != modelindex ) { continue; } //if the level item is linked to an entity if ( li->entitynum ) { if ( li->entitynum == ent ) { VectorCopy( entinfo.origin, li->origin ); break; } //end if } //end if else { //check if the entity is very close VectorSubtract( li->origin, entinfo.origin, dir ); if ( VectorLength( dir ) < 30 ) { //found an entity for this level item li->entitynum = ent; //keep updating the entity origin VectorCopy( entinfo.origin, li->origin ); //also update the goal area number li->goalareanum = AAS_BestReachableArea( li->origin, ic->iteminfo[li->iteminfo].mins, ic->iteminfo[li->iteminfo].maxs, li->goalorigin ); //Log_Write("found item %s entity", ic->iteminfo[li->iteminfo].classname); break; } //end if //else botimport.Print(PRT_MESSAGE, "item %s has no attached entity\n", // ic->iteminfo[li->iteminfo].name); } //end else } //end for if ( li ) { continue; } //check if the model is from a known item for ( i = 0; i < ic->numiteminfo; i++ ) { if ( ic->iteminfo[i].modelindex == modelindex ) { break; } //end if } //end for //if the model is not from a known item if ( i >= ic->numiteminfo ) { continue; } //allocate a new level item li = AllocLevelItem(); // if ( !li ) { continue; } //entity number of the level item li->entitynum = ent; //number for the level item li->number = numlevelitems + ent; //set the item info index for the level item li->iteminfo = i; //origin of the item VectorCopy( entinfo.origin, li->origin ); //get the item goal area and goal origin li->goalareanum = AAS_BestReachableArea( li->origin, ic->iteminfo[i].mins, ic->iteminfo[i].maxs, li->goalorigin ); // if ( AAS_AreaJumpPad( li->goalareanum ) ) { FreeLevelItem( li ); continue; } //end if //time this item out after 30 seconds //dropped items disappear after 30 seconds li->timeout = AAS_Time() + 30; //add the level item to the list AddLevelItemToList( li ); //botimport.Print(PRT_MESSAGE, "found new level item %s\n", ic->iteminfo[i].classname); } //end for } //end of the function BotUpdateEntityItems
void BotUpdateEntityItems() { int ent, i, modelindex; vec3_t dir; levelitem_t* li, * nextli; aas_entityinfo_t entinfo; itemconfig_t* ic; //timeout current entity items if necessary for ( li = levelitems; li; li = nextli ) { nextli = li->next; //if it is a item that will time out if ( li->timeout ) { //timeout the item if ( li->timeout < AAS_Time() ) { RemoveLevelItemFromList( li ); FreeLevelItem( li ); } //end if } //end if } //end for //find new entity items ic = itemconfig; if ( !itemconfig ) { return; } // for ( ent = AAS_NextEntity( 0 ); ent; ent = AAS_NextEntity( ent ) ) { if ( AAS_EntityType( ent ) != Q3ET_ITEM ) { continue; } //get the model index of the entity modelindex = AAS_EntityModelindex( ent ); // if ( !modelindex ) { continue; } //get info about the entity AAS_EntityInfo( ent, &entinfo ); //FIXME: don't do this //skip all floating items for now if ( !( GGameType & GAME_Quake3 ) && entinfo.groundent != Q3ENTITYNUM_WORLD ) { continue; } //if the entity is still moving if ( entinfo.origin[ 0 ] != entinfo.lastvisorigin[ 0 ] || entinfo.origin[ 1 ] != entinfo.lastvisorigin[ 1 ] || entinfo.origin[ 2 ] != entinfo.lastvisorigin[ 2 ] ) { continue; } //check if the entity is already stored as a level item for ( li = levelitems; li; li = li->next ) { if ( GGameType & GAME_Quake3 ) { //if the level item is linked to an entity if ( li->entitynum && li->entitynum == ent ) { //the entity is re-used if the models are different if ( ic->iteminfo[ li->iteminfo ].modelindex != modelindex ) { //remove this level item RemoveLevelItemFromList( li ); FreeLevelItem( li ); li = NULL; break; } else { if ( entinfo.origin[ 0 ] != li->origin[ 0 ] || entinfo.origin[ 1 ] != li->origin[ 1 ] || entinfo.origin[ 2 ] != li->origin[ 2 ] ) { VectorCopy( entinfo.origin, li->origin ); //also update the goal area number li->goalareanum = AAS_BestReachableArea( li->origin, ic->iteminfo[ li->iteminfo ].mins, ic->iteminfo[ li->iteminfo ].maxs, li->goalorigin ); } break; } } } else { //if the model of the level item and the entity are different if ( ic->iteminfo[ li->iteminfo ].modelindex != modelindex ) { continue; } //if the level item is linked to an entity if ( li->entitynum ) { if ( li->entitynum == ent ) { VectorCopy( entinfo.origin, li->origin ); break; } //end if } //end if else { //check if the entity is very close VectorSubtract( li->origin, entinfo.origin, dir ); if ( VectorLength( dir ) < 30 ) { //found an entity for this level item li->entitynum = ent; //keep updating the entity origin VectorCopy( entinfo.origin, li->origin ); //also update the goal area number li->goalareanum = AAS_BestReachableArea( li->origin, ic->iteminfo[ li->iteminfo ].mins, ic->iteminfo[ li->iteminfo ].maxs, li->goalorigin ); //Log_Write("found item %s entity", ic->iteminfo[li->iteminfo].classname); break; } //end if //else BotImport_Print(PRT_MESSAGE, "item %s has no attached entity\n", // ic->iteminfo[li->iteminfo].name); } //end else } } //end for if ( li ) { continue; } if ( GGameType & GAME_Quake3 ) { //try to link the entity to a level item for ( li = levelitems; li; li = li->next ) { //if this level item is already linked if ( li->entitynum ) { continue; } if ( g_gametype == Q3GT_SINGLE_PLAYER ) { if ( li->flags & IFL_NOTSINGLE ) { continue; } } else if ( g_gametype >= Q3GT_TEAM ) { if ( li->flags & IFL_NOTTEAM ) { continue; } } else { if ( li->flags & IFL_NOTFREE ) { continue; } } //if the model of the level item and the entity are the same if ( ic->iteminfo[ li->iteminfo ].modelindex == modelindex ) { //check if the entity is very close VectorSubtract( li->origin, entinfo.origin, dir ); if ( VectorLength( dir ) < 30 ) { //found an entity for this level item li->entitynum = ent; //if the origin is different if ( entinfo.origin[ 0 ] != li->origin[ 0 ] || entinfo.origin[ 1 ] != li->origin[ 1 ] || entinfo.origin[ 2 ] != li->origin[ 2 ] ) { //update the level item origin VectorCopy( entinfo.origin, li->origin ); //also update the goal area number li->goalareanum = AAS_BestReachableArea( li->origin, ic->iteminfo[ li->iteminfo ].mins, ic->iteminfo[ li->iteminfo ].maxs, li->goalorigin ); } #ifdef DEBUG Log_Write( "linked item %s to an entity", ic->iteminfo[ li->iteminfo ].classname ); #endif break; } } } if ( li ) { continue; } } //check if the model is from a known item for ( i = 0; i < ic->numiteminfo; i++ ) { if ( ic->iteminfo[ i ].modelindex == modelindex ) { break; } //end if } //end for //if the model is not from a known item if ( i >= ic->numiteminfo ) { continue; } //allocate a new level item li = AllocLevelItem(); // if ( !li ) { continue; } //entity number of the level item li->entitynum = ent; //number for the level item li->number = numlevelitems + ent; //set the item info index for the level item li->iteminfo = i; //origin of the item VectorCopy( entinfo.origin, li->origin ); //get the item goal area and goal origin li->goalareanum = AAS_BestReachableArea( li->origin, ic->iteminfo[ i ].mins, ic->iteminfo[ i ].maxs, li->goalorigin ); //never go for items dropped into jumppads if ( AAS_AreaJumpPad( li->goalareanum ) ) { FreeLevelItem( li ); continue; } //end if //time this item out after 30 seconds //dropped items disappear after 30 seconds li->timeout = AAS_Time() + 30; //add the level item to the list AddLevelItemToList( li ); } }