Пример #1
0
/*
============
idAASLocal::ShowWallEdges
============
*/
void idAASLocal::ShowWallEdges( const idVec3 &origin ) const {
	int i, areaNum, numEdges, edges[1024];
	idVec3 start, end;
	idPlayer *player;

	player = gameLocal.GetLocalPlayer();
	if ( !player ) {
		return;
	}

	areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), (AREA_REACHABLE_WALK|AREA_REACHABLE_FLY) );
	numEdges = GetWallEdges( areaNum, idBounds( origin ).Expand( 256.0f ), TFL_WALK, edges, 1024 );
	for ( i = 0; i < numEdges; i++ ) {
		GetEdge( edges[i], start, end );
		gameRenderWorld->DebugLine( colorRed, start, end );
		gameRenderWorld->DrawText( va( "%d", edges[i] ), ( start + end ) * 0.5f, 0.1f, colorWhite, player->viewAxis );
	}
}
Пример #2
0
/*
============
idAASLocal::ShowHideArea
============
*/
void idAASLocal::ShowHideArea( const idVec3 &origin, int targetAreaNum ) const {
	int areaNum, numObstacles;
	idVec3 target;
	aasGoal_t goal;
	aasObstacle_t obstacles[10];
	areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), ( AREA_REACHABLE_WALK | AREA_REACHABLE_FLY ) );
	target = AreaCenter( targetAreaNum );
	// consider the target an obstacle
	obstacles[0].absBounds = idBounds( target ).Expand( 16 );
	numObstacles = 1;
	DrawCone( target, idVec3( 0, 0, 1 ), 16.0f, colorYellow );
	idAASFindCover findCover( target );
	if( FindNearestGoal( goal, areaNum, origin, target, TFL_WALK | TFL_AIR, obstacles, numObstacles, findCover ) ) {
		DrawArea( goal.areaNum );
		ShowWalkPath( origin, goal.areaNum, goal.origin );
		DrawCone( goal.origin, idVec3( 0, 0, 1 ), 16.0f, colorWhite );
	}
}
Пример #3
0
/*
============
idAASLocal::GetAreaNumAndLocation
============
*/
bool idAASLocal::GetAreaNumAndLocation( idCVar &cvar, const idVec3 &origin, int &areaNum, idVec3 &location ) const {

	areaNum = 0;
	location.Zero();

	if ( cvar.GetString()[0] == '\0' ) {
		return false;
	}

	if ( idStr::Icmp( cvar.GetString(), "memory" ) == 0 ) {
		cvar.SetString( aas_locationMemory.GetString() );
	}

	if ( idStr::Icmp( cvar.GetString(), "current" ) == 0 ) {
		cvar.SetString( origin.ToString() );
	}

	idLexer src( LEXFL_NOERRORS|LEXFL_NOWARNINGS );
	src.LoadMemory( cvar.GetString(), idStr::Length( cvar.GetString() ), "areaNum" );

	bool error = false;
	location.x = src.ParseFloat( &error );
	location.y = src.ParseFloat( &error );
	location.z = src.ParseFloat( &error );

	if ( !error ) {
		areaNum = PointReachableAreaNum( location, DefaultSearchBounds(), AAS_AREA_REACHABLE_WALK, TravelFlagInvalidForTeam() );
		PushPointIntoArea( areaNum, location );
		return true;
	}

	src.Reset();

	areaNum = src.ParseInt();

	if ( ( areaNum > 0 ) && ( areaNum < file->GetNumAreas() ) ) {
		location = AreaCenter( areaNum );
		return true;
	}

	return false;
}
Пример #4
0
/*
============
idAASLocal::ShowFlyPath
============
*/
void idAASLocal::ShowFlyPath(const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin) const
{
	int i, areaNum, curAreaNum, travelTime;
	idReachability *reach;
	idVec3 org, areaCenter;
	aasPath_t path;

	if (!file) {
		return;
	}

	org = origin;
	areaNum = PointReachableAreaNum(org, DefaultSearchBounds(), AREA_REACHABLE_FLY);
	PushPointIntoAreaNum(areaNum, org);
	curAreaNum = areaNum;

	for (i = 0; i < 100; i++) {

		if (!RouteToGoalArea(curAreaNum, org, goalAreaNum, TFL_WALK|TFL_FLY|TFL_AIR, travelTime, &reach)) {
			break;
		}

		if (!reach) {
			break;
		}

		gameRenderWorld->DebugArrow(colorPurple, org, reach->start, 2);
		DrawReachability(reach);

		if (reach->toAreaNum == goalAreaNum) {
			break;
		}

		curAreaNum = reach->toAreaNum;
		org = reach->end;
	}

	if (FlyPathToGoal(path, areaNum, origin, goalAreaNum, goalOrigin, TFL_WALK|TFL_FLY|TFL_AIR)) {
		gameRenderWorld->DebugArrow(colorBlue, origin, path.moveGoal, 2);
	}
}
Пример #5
0
/*
============
idAASLocal::PullPlayer
============
*/
bool idAASLocal::PullPlayer( const idVec3 &origin, int toAreaNum ) const {
	int areaNum;
	idVec3 areaCenter, dir, vel;
	idAngles delta;
	aasPath_t path;
	idPlayer *player;
	player = gameLocal.GetLocalPlayer();
	if( !player ) {
		return true;
	}
	idPhysics *physics = player->GetPhysics();
	if( !physics ) {
		return true;
	}
	if( !toAreaNum ) {
		return false;
	}
	areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), ( AREA_REACHABLE_WALK | AREA_REACHABLE_FLY ) );
	areaCenter = AreaCenter( toAreaNum );
	if( player->GetPhysics()->GetAbsBounds().Expand( 8 ).ContainsPoint( areaCenter ) ) {
		return false;
	}
	if( WalkPathToGoal( path, areaNum, origin, toAreaNum, areaCenter, TFL_WALK | TFL_AIR ) ) {
		dir = path.moveGoal - origin;
		dir[2] *= 0.5f;
		dir.Normalize();
		delta = dir.ToAngles() - player->cmdAngles - player->GetDeltaViewAngles();
		delta.Normalize180();
		player->SetDeltaViewAngles( player->GetDeltaViewAngles() + delta * 0.1f );
		dir[2] = 0.0f;
		dir.Normalize();
		dir *= 100.0f;
		vel = physics->GetLinearVelocity();
		dir[2] = vel[2];
		physics->SetLinearVelocity( dir );
		return true;
	} else {
		return false;
	}
}
Пример #6
0
/*
============
idAASLocal::ShowFloorTrace
============
*/
void idAASLocal::ShowFloorTrace( const idVec3 &origin ) const {
	idPlayer *player;

	player = gameLocal.GetLocalPlayer();
	if ( !player ) {
		return;
	}
	idMat3 playerAxis = idAngles( 0.0f, player->GetViewAngles().yaw, 0.0f ).ToMat3();

	idVec3 org = origin;
	int areaNum = PointReachableAreaNum( org, DefaultSearchBounds(), AAS_AREA_REACHABLE_WALK, TravelFlagInvalidForTeam() );
	PushPointIntoArea( areaNum, org );

	aasTraceFloor_t trace;
	TraceFloor( trace, org, areaNum, origin + playerAxis[0] * 1024, TFL_WALK|TFL_AIR );

	gameRenderWorld->DebugArrow( colorCyan, org, trace.endpos, 1, 0 );
	idVec3 up = trace.endpos + playerAxis[2] * 64;
	const idVec4 &color = ( trace.fraction >= 1.0f ) ? colorGreen : colorRed;
	gameRenderWorld->DebugArrow( color, trace.endpos, up + playerAxis[1] * 32, 1, 0, true );
	gameRenderWorld->DebugArrow( color, trace.endpos, up - playerAxis[1] * 32, 1, 0, true );
}
Пример #7
0
/*
============
idAASLocal::ShowArea
============
*/
void idAASLocal::ShowArea( const idVec3& origin ) const
{
	static int lastAreaNum;
	int areaNum;
	const aasArea_t* area;
	idVec3 org;
	
	areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), ( AREA_REACHABLE_WALK | AREA_REACHABLE_FLY ) );
	org = origin;
	PushPointIntoAreaNum( areaNum, org );
	
	if( aas_goalArea.GetInteger() )
	{
		int travelTime;
		idReachability* reach;
		
		RouteToGoalArea( areaNum, org, aas_goalArea.GetInteger(), TFL_WALK | TFL_AIR, travelTime, &reach );
		gameLocal.Printf( "\rtt = %4d", travelTime );
		if( reach )
		{
			gameLocal.Printf( " to area %4d", reach->toAreaNum );
			DrawArea( reach->toAreaNum );
		}
	}
	
	if( areaNum != lastAreaNum )
	{
		area = &file->GetArea( areaNum );
		gameLocal.Printf( "area %d: ", areaNum );
		if( area->flags & AREA_LEDGE )
		{
			gameLocal.Printf( "AREA_LEDGE " );
		}
		if( area->flags & AREA_REACHABLE_WALK )
		{
			gameLocal.Printf( "AREA_REACHABLE_WALK " );
		}
		if( area->flags & AREA_REACHABLE_FLY )
		{
			gameLocal.Printf( "AREA_REACHABLE_FLY " );
		}
		if( area->contents & AREACONTENTS_CLUSTERPORTAL )
		{
			gameLocal.Printf( "AREACONTENTS_CLUSTERPORTAL " );
		}
		if( area->contents & AREACONTENTS_OBSTACLE )
		{
			gameLocal.Printf( "AREACONTENTS_OBSTACLE " );
		}
		gameLocal.Printf( "\n" );
		lastAreaNum = areaNum;
	}
	
	if( org != origin )
	{
		idBounds bnds = file->GetSettings().boundingBoxes[ 0 ];
		bnds[ 1 ].z = bnds[ 0 ].z;
		gameRenderWorld->DebugBounds( colorYellow, bnds, org );
	}
	
	DrawArea( areaNum );
}
Пример #8
0
/*
============
idAASLocal::PullPlayer
============
*/
bool idAASLocal::PullPlayer( const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin, int &startAreaNum, int &travelTime ) const {

	startAreaNum = 0;
	travelTime = 0;

	idPlayer *player = gameLocal.GetLocalPlayer();
	if ( player == NULL ) {
		return true;
	}

	if ( goalAreaNum == 0 ) {
		return false;
	}

	if ( player->GetNoClip() ) {
		player->aasPullPlayer = false;
		return false;
	}

	idVec3 dir = goalOrigin - origin;
	float height = idMath::Fabs( dir.z );
	float dist = dir.ToVec2().Length();

	if ( dist < 32.0f && height < 128.0f ) {
		return false;
	}

	idVec3 org = origin;
	startAreaNum = PointReachableAreaNum( org, DefaultSearchBounds(), AAS_AREA_REACHABLE_WALK, TravelFlagInvalidForTeam() );
	PushPointIntoArea( startAreaNum, org );

	const aasReachability_t *reach;
	RouteToGoalArea( startAreaNum, org, goalAreaNum, TravelFlagForTeam(), travelTime, &reach );

	ShowWalkPath( startAreaNum, org, goalAreaNum, goalOrigin, TravelFlagForTeam(), TravelFlagWalkForTeam() );

	idAASPath path;
	if ( !WalkPathToGoal( path, startAreaNum, org, goalAreaNum, goalOrigin, TravelFlagForTeam(), TravelFlagWalkForTeam() ) ) {
		return false;
	}

	idObstacleAvoidance::obstaclePath_t obstaclePath;
	idObstacleAvoidance obstacleAvoidance;
	botThreadData.BuildObstacleList( obstacleAvoidance, org, startAreaNum, false );
	obstacleAvoidance.FindPathAroundObstacles( file->GetSettings().boundingBox, file->GetSettings().obstaclePVSRadius, this, org, path.moveGoal, obstaclePath );
	path.moveGoal = obstaclePath.seekPos;

	player->aasPullPlayer = true;

	usercmd_t usercmd;
	memset( &usercmd, 0, sizeof( usercmd ) );

	usercmd.forwardmove = 127;
	usercmd.buttons.btn.run = true;
	usercmd.buttons.btn.sprint = false;

	idVec3 moveDir = path.moveGoal - org;
	idVec3 horizontalDir( moveDir.x, moveDir.y, 0.0f );
	float horizontalDist = horizontalDir.Normalize();
	moveDir.Normalize();

	switch( path.type ) {
		case PATHTYPE_WALKOFFLEDGE:
		case PATHTYPE_WALKOFFBARRIER: {
			if ( horizontalDist < 80.0f ) {
				usercmd.buttons.btn.run = false;
				usercmd.forwardmove = 16 + horizontalDist;
			}
			break;
		}
		case PATHTYPE_BARRIERJUMP:
		case PATHTYPE_JUMP: {
			if ( horizontalDist < 24.0f ) {
				pullPlayerState.jumpNow = !pullPlayerState.jumpNow;
				if ( pullPlayerState.jumpNow ) {
					usercmd.upmove = 127;
				}
			}
			if ( player->GetPlayerPhysics().IsGrounded() ) {
				if ( horizontalDist < 100.0f ) {
					usercmd.buttons.btn.run = false;
					usercmd.forwardmove = 8 + horizontalDist;
				}
			} else {
				moveDir = path.reachability->GetEnd() - org;
				moveDir.Normalize();
			}
			break;
		}
		case PATHTYPE_LADDER: {
			pullPlayerState.ladderDir = moveDir;
			pullPlayerState.ladderTime = gameLocal.time;
#if 0
			// test ladder physics code
			if ( !player->GetPlayerPhysics().IsGrounded() ) {
				trace_t trace;
				bool onLadder = false;
				if ( gameLocal.clip.Translation( CLIP_DEBUG_PARMS_CLIENTINFO( self ) trace, org, org + horizontalDir * 32.0f, NULL, mat3_identity, MASK_PLAYERSOLID, player ) ) {
					onLadder = ( gameLocal.entities[ trace.c.entityNum ]->Cast< sdLadderEntity >() != NULL );
				}
				if ( onLadder && !player->GetPlayerPhysics().OnLadder() ) {
					usercmd.forwardmove = 0;
				}
			}
#endif
			break;
		}
	}

	if ( player->GetPlayerPhysics().OnLadder() || pullPlayerState.ladderTime > gameLocal.time - 500 ) {
		moveDir = pullPlayerState.ladderDir;
	}

	idAngles viewAngles = moveDir.ToAngles();

	player->Move( usercmd, viewAngles );

	return true;
}
Пример #9
0
/*
============
idAASLocal::ShowWallEdges
============
*/
void idAASLocal::ShowWallEdges( const idVec3 &origin, int mode, bool showNumbers ) const {
	const int MAX_WALL_EDGES = 1024;
	int edges[MAX_WALL_EDGES];
	float textSize;

	idPlayer *player = gameLocal.GetLocalPlayer();
	if ( player == NULL ) {
		return;
	}

	idMat3 viewAxis = player->GetViewAxis();
	idVec3 viewOrigin = player->GetViewPos();
	idMat3 playerAxis = idAngles( 0.0f, -player->GetViewAngles().yaw, 0.0f ).ToMat3();

	if ( mode == 3 ) {
		textSize = 0.2f;
	} else {
		textSize = 0.1f;
	}

	float radius = file->GetSettings().obstaclePVSRadius;

	int areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), AAS_AREA_REACHABLE_WALK, TravelFlagInvalidForTeam() );
	//int numEdges = GetWallEdges( areaNum, idBounds( origin ).Expand( radius ), TFL_WALK, 64.0f, edges, MAX_WALL_EDGES );
	int numEdges = GetObstaclePVSWallEdges( areaNum, edges, MAX_WALL_EDGES );

	// move the wall edges to the start of the list
	int numWallEdges = 0;
	for ( int i = 0; i < numEdges; i++ ) {
		if ( ( file->GetEdge( abs( edges[i] ) ).flags & AAS_EDGE_WALL ) != 0 ) {
			idSwap( edges[numWallEdges++], edges[i] );
		}
	}

	for ( int i = 0; i < numEdges; i++ ) {
		idVec3 start, end;

		GetEdge( edges[i], start, end );

		if ( mode == 2 ) {

			start.z = end.z = origin.z;

		} else if ( mode == 3 ) {

			ProjectTopDown( start, viewOrigin, viewAxis, playerAxis, radius * 2.0f );
			ProjectTopDown( end, viewOrigin, viewAxis, playerAxis, radius * 2.0f );
		}

		if ( ( file->GetEdge( abs( edges[i] ) ).flags & AAS_EDGE_WALL ) != 0 ) {
			gameRenderWorld->DebugLine( colorRed, start, end, 0 );
		} else {
			gameRenderWorld->DebugLine( colorGreen, start, end, 0 );
		}
		if ( showNumbers ) {
			gameRenderWorld->DrawText( va( "%d", edges[i] ), ( start + end ) * 0.5f, textSize, colorWhite, viewAxis, 1, 0 );
		}
	}

	if ( mode == 3 ) {
		idVec3 box[7] = { origin, origin, origin, origin, origin, origin, origin };

		box[0][0] += radius;
		box[0][1] += radius;

		box[1][0] += radius;
		box[1][1] -= radius;

		box[2][0] -= radius;
		box[2][1] -= radius;

		box[3][0] -= radius;
		box[3][1] += radius;

		box[4][1] += radius;

		box[5][0] += radius * 0.1f;
		box[5][1] += radius - radius * 0.1f;

		box[6][0] -= radius * 0.1f;
		box[6][1] += radius - radius * 0.1f;

		for ( int i = 0; i < 7; i++ ) {
			ProjectTopDown( box[i], viewOrigin, viewAxis, playerAxis, radius * 2.0f );
		}
		for ( int i = 0; i < 4; i++ ) {
			gameRenderWorld->DebugLine( colorCyan, box[i], box[(i+1)&3], 0 );
		}
		gameRenderWorld->DebugLine( colorCyan, box[4], box[5], 0 );
		gameRenderWorld->DebugLine( colorCyan, box[4], box[6], 0 );
	}
}
Пример #10
0
/*
============
idAASLocal::ShowArea
============
*/
void idAASLocal::ShowArea( const idVec3 &origin, int mode ) const {
	static int lastAreaNum;
	int areaNum;
	const aasArea_t *area;
	idVec3 org;

	org = origin;
	if ( mode == 1 ) {
		areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), AAS_AREA_REACHABLE_WALK, TravelFlagInvalidForTeam() );
		PushPointIntoArea( areaNum, org );
	} else {
		areaNum = PointAreaNum( origin );
	}

	if ( aas_showTravelTime.GetInteger() ) {
		int travelTime;
		const aasReachability_t *reach;
		
		RouteToGoalArea( areaNum, org, aas_showTravelTime.GetInteger(), TFL_WALK|TFL_AIR, travelTime, &reach );
		gameLocal.Printf( "\rtt = %4d", travelTime );
		if ( reach ) {
			gameLocal.Printf( " to area %4d", reach->toAreaNum );
			DrawArea( reach->toAreaNum );
		}
	}

	if ( areaNum != lastAreaNum ) {
		area = &file->GetArea( areaNum );
		gameLocal.Printf( "area %d:", areaNum );
		if ( area->flags & AAS_AREA_LEDGE ) {
			gameLocal.Printf( " ledge" );
		}
		if ( area->flags & AAS_AREA_CONTENTS_CLUSTERPORTAL ) {
			gameLocal.Printf( " clusterportal" );
		}
		if ( area->flags & AAS_AREA_CONTENTS_OBSTACLE ) {
			gameLocal.Printf( " obstacle" );
		}
		if ( area->flags & AAS_AREA_OUTSIDE ) {
			gameLocal.Printf( " outside" );
		}
		if ( area->flags & AAS_AREA_HIGH_CEILING ) {
			gameLocal.Printf( " highceiling" );
		}
		if ( area->travelFlags & ( TFL_INVALID | TFL_INVALID_GDF | TFL_INVALID_STROGG ) ) {
			gameLocal.Printf( " /" );
			if ( area->travelFlags & TFL_INVALID ) {
				gameLocal.Printf( " invalid" );
			}
			if ( area->travelFlags & TFL_INVALID_GDF ) {
				gameLocal.Printf( " invalidgdf" );
			}
			if ( area->travelFlags & TFL_INVALID_STROGG ) {
				gameLocal.Printf( " invalidstrogg" );
			}
		}
		gameLocal.Printf( "\n" );
		lastAreaNum = areaNum;
	}

	if ( org != origin ) {
		idBounds bnds = file->GetSettings().boundingBox;
		bnds[ 1 ].z = bnds[ 0 ].z;
		gameRenderWorld->DebugBounds( colorYellow, bnds, org );
		gameRenderWorld->DebugArrow( colorYellow, origin, org, 1 );
	}

	DrawArea( areaNum );
}