示例#1
0
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
示例#2
0
void BotInitLevelItems() {
	//initialize the map locations and camp spots
	BotInitInfoEntities();

	//initialize the level item heap
	InitLevelItemHeap();
	levelitems = NULL;
	numlevelitems = 0;

	itemconfig_t* ic = itemconfig;
	if ( !ic ) {
		return;
	}

	//if there's no AAS file loaded
	if ( !AAS_Loaded() ) {
		return;
	}

	//update the modelindexes of the item info
	for ( int i = 0; i < ic->numiteminfo; i++ ) {
		if ( !ic->iteminfo[ i ].modelindex ) {
			Log_Write( "item %s has modelindex 0", ic->iteminfo[ i ].classname );
		}
	}

	for ( int ent = AAS_NextBSPEntity( 0 ); ent; ent = AAS_NextBSPEntity( ent ) ) {
		char classname[ MAX_EPAIRKEY ];
		if ( !AAS_ValueForBSPEpairKey( ent, "classname", classname, MAX_EPAIRKEY ) ) {
			continue;
		}

		int spawnflags = 0;
		AAS_IntForBSPEpairKey( ent, "spawnflags", &spawnflags );

		int i;
		for ( i = 0; i < ic->numiteminfo; i++ ) {
			if ( !String::Cmp( classname, ic->iteminfo[ i ].classname ) ) {
				break;
			}
		}
		if ( i >= ic->numiteminfo ) {
			Log_Write( "entity %s unknown item\r\n", classname );
			continue;
		}
		//get the origin of the item
		vec3_t origin;
		if ( !AAS_VectorForBSPEpairKey( ent, "origin", origin ) ) {
			BotImport_Print( PRT_ERROR, "item %s without origin\n", classname );
			continue;
		}

		int goalareanum = 0;
		//if it is a floating item
		if ( spawnflags & 1 ) {
			if ( !( GGameType & GAME_Quake3 ) ) {
				continue;
			}
			//if the item is not floating in water
			if ( !( AAS_PointContents( origin ) & BSP46CONTENTS_WATER ) ) {
				vec3_t end;
				VectorCopy( origin, end );
				end[ 2 ] -= 32;
				bsp_trace_t trace = AAS_Trace( origin, ic->iteminfo[ i ].mins, ic->iteminfo[ i ].maxs, end, -1, BSP46CONTENTS_SOLID | BSP46CONTENTS_PLAYERCLIP );
				//if the item not near the ground
				if ( trace.fraction >= 1 ) {
					//if the item is not reachable from a jumppad
					goalareanum = AAS_BestReachableFromJumpPadArea( origin, ic->iteminfo[ i ].mins, ic->iteminfo[ i ].maxs );
					Log_Write( "item %s reachable from jumppad area %d\r\n", ic->iteminfo[ i ].classname, goalareanum );
					if ( !goalareanum ) {
						continue;
					}
				}
			}
		}

		levelitem_t* li = AllocLevelItem();
		if ( !li ) {
			return;
		}

		li->number = ++numlevelitems;
		li->timeout = 0;
		li->entitynum = 0;

		li->flags = 0;
		int value;
		AAS_IntForBSPEpairKey( ent, "notfree", &value );
		if ( value ) {
			li->flags |= IFL_NOTFREE;
		}
		AAS_IntForBSPEpairKey( ent, "notteam", &value );
		if ( value ) {
			li->flags |= IFL_NOTTEAM;
		}
		AAS_IntForBSPEpairKey( ent, "notsingle", &value );
		if ( value ) {
			li->flags |= IFL_NOTSINGLE;
		}
		if ( GGameType & GAME_Quake3 ) {
			AAS_IntForBSPEpairKey( ent, "notbot", &value );
			if ( value ) {
				li->flags |= IFL_NOTBOT;
			}
			if ( !String::Cmp( classname, "item_botroam" ) ) {
				li->flags |= IFL_ROAM;
				AAS_FloatForBSPEpairKey( ent, "weight", &li->weight );
			}
		}
		//if not a stationary item
		if ( !( spawnflags & 1 ) ) {
			if ( !AAS_DropToFloor( origin, ic->iteminfo[ i ].mins, ic->iteminfo[ i ].maxs ) ) {
				BotImport_Print( PRT_MESSAGE, "%s in solid at (%1.1f %1.1f %1.1f)\n",
					classname, origin[ 0 ], origin[ 1 ], origin[ 2 ] );
			}
		}
		//item info of the level item
		li->iteminfo = i;
		//origin of the item
		VectorCopy( origin, li->origin );

		if ( goalareanum ) {
			li->goalareanum = goalareanum;
			VectorCopy( origin, li->goalorigin );
		} else {
			//get the item goal area and goal origin
			li->goalareanum = AAS_BestReachableArea( origin,
				ic->iteminfo[ i ].mins, ic->iteminfo[ i ].maxs,
				li->goalorigin );
			if ( !li->goalareanum ) {
				BotImport_Print( PRT_MESSAGE, "%s not reachable for bots at (%1.1f %1.1f %1.1f)\n",
					classname, origin[ 0 ], origin[ 1 ], origin[ 2 ] );
			}
		}

		AddLevelItemToList( li );
	}
	BotImport_Print( PRT_MESSAGE, "found %d level items\n", numlevelitems );
}
示例#3
0
//===========================================================================
//
// Parameter:			-
// Returns:				-
// Changes Globals:		-
//===========================================================================
void BotInitLevelItems( void ) {
	int i, spawnflags;
	char classname[MAX_EPAIRKEY];
	vec3_t origin;
	int ent;
	itemconfig_t *ic;
	levelitem_t *li;

	//initialize the map locations and camp spots
	BotInitInfoEntities();

	//initialize the level item heap
	InitLevelItemHeap();
	levelitems = NULL;
	numlevelitems = 0;
	//
	ic = itemconfig;
	if ( !ic ) {
		return;
	}

	//if there's no AAS file loaded
	if ( !AAS_Loaded() ) {
		return;
	}

	//update the modelindexes of the item info
	for ( i = 0; i < ic->numiteminfo; i++ )
	{
		//ic->iteminfo[i].modelindex = AAS_IndexFromModel(ic->iteminfo[i].model);
		if ( !ic->iteminfo[i].modelindex ) {
			Log_Write( "item %s has modelindex 0", ic->iteminfo[i].classname );
		} //end if
	} //end for

	for ( ent = AAS_NextBSPEntity( 0 ); ent; ent = AAS_NextBSPEntity( ent ) )
	{
		if ( !AAS_ValueForBSPEpairKey( ent, "classname", classname, MAX_EPAIRKEY ) ) {
			continue;
		}
		//
		spawnflags = 0;
		AAS_IntForBSPEpairKey( ent, "spawnflags", &spawnflags );
		//FIXME: don't do this
		// for now skip all floating entities
		if ( spawnflags & 1 ) {
			continue;
		}
		//
		for ( i = 0; i < ic->numiteminfo; i++ )
		{
			if ( !strcmp( classname, ic->iteminfo[i].classname ) ) {
				//get the origin of the item
				if ( AAS_VectorForBSPEpairKey( ent, "origin", origin ) ) {
					li = AllocLevelItem();
					if ( !li ) {
						return;
					}
					//
					li->number = ++numlevelitems;
					li->timeout = 0;
					li->entitynum = 0;
					//
					AAS_IntForBSPEpairKey( ent, "notfree", &li->notfree );
					AAS_IntForBSPEpairKey( ent, "notteam", &li->notteam );
					AAS_IntForBSPEpairKey( ent, "notsingle", &li->notsingle );
					//if not a stationary item
					if ( !( spawnflags & 1 ) ) {
						if ( !AAS_DropToFloor( origin, ic->iteminfo[i].mins, ic->iteminfo[i].maxs ) ) {
							botimport.Print( PRT_MESSAGE, "%s in solid at (%1.1f %1.1f %1.1f)\n",
											 classname, origin[0], origin[1], origin[2] );
						} //end if
					} //end if
					  //item info of the level item
					li->iteminfo = i;
					//origin of the item
					VectorCopy( origin, li->origin );
					//get the item goal area and goal origin
					li->goalareanum = AAS_BestReachableArea( origin,
															 ic->iteminfo[i].mins, ic->iteminfo[i].maxs,
															 li->goalorigin );
					//
					AddLevelItemToList( li );
				} //end if
				else
				{
					botimport.Print( PRT_ERROR, "item %s without origin\n", classname );
				} //end else
				break;
			} //end if
		} //end for
		if ( i >= ic->numiteminfo ) {
			Log_Write( "entity %s unknown item\r\n", classname );
		} //end if
	} //end for
	botimport.Print( PRT_MESSAGE, "found %d level items\n", numlevelitems );
} //end of the function BotInitLevelItems
示例#4
0
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 );
	}
}