/* ============ idAASLocal::Test ============ */ void idAASLocal::Test( const idVec3 &origin ) { if ( !file ) { return; } if ( aas_randomPullPlayer.GetBool() ) { RandomPullPlayer( origin ); } if ( ( aas_pullPlayer.GetInteger() > 0 ) && ( aas_pullPlayer.GetInteger() < file->GetNumAreas() ) ) { ShowWalkPath( origin, aas_pullPlayer.GetInteger(), AreaCenter( aas_pullPlayer.GetInteger() ) ); PullPlayer( origin, aas_pullPlayer.GetInteger() ); } if ( ( aas_showPath.GetInteger() > 0 ) && ( aas_showPath.GetInteger() < file->GetNumAreas() ) ) { ShowWalkPath( origin, aas_showPath.GetInteger(), AreaCenter( aas_showPath.GetInteger() ) ); } if ( ( aas_showFlyPath.GetInteger() > 0 ) && ( aas_showFlyPath.GetInteger() < file->GetNumAreas() ) ) { ShowFlyPath( origin, aas_showFlyPath.GetInteger(), AreaCenter( aas_showFlyPath.GetInteger() ) ); } if ( ( aas_showHideArea.GetInteger() > 0 ) && ( aas_showHideArea.GetInteger() < file->GetNumAreas() ) ) { ShowHideArea( origin, aas_showHideArea.GetInteger() ); } if ( aas_showAreas.GetBool() ) { ShowArea( origin ); } if ( aas_showWallEdges.GetBool() ) { ShowWallEdges( origin ); } if ( aas_showPushIntoArea.GetBool() ) { ShowPushIntoArea( origin ); } }
/* ============ idAASLocal::ShowNearestInsideArea ============ */ void idAASLocal::ShowNearestInsideArea( const idVec3 &origin ) const { int areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), AAS_AREA_REACHABLE_WALK, TravelFlagInvalidForTeam() ); idAASCallback_FindFlaggedArea findInside( AAS_AREA_OUTSIDE, false ); idAASGoal goal; if ( FindNearestGoal( goal, areaNum, origin, TravelFlagForTeam(), findInside ) ) { DrawArea( goal.areaNum ); ShowWalkPath( areaNum, origin, goal.areaNum, goal.origin, TravelFlagForTeam(), TravelFlagWalkForTeam() ); DrawCone( goal.origin, idVec3( 0, 0, 1 ), 16.0f, colorWhite ); } }
/* ============ idAASLocal::RandomPullPlayer ============ */ void idAASLocal::RandomPullPlayer( const idVec3 &origin ) const { int rnd, i, n; if( !PullPlayer( origin, aas_pullPlayer.GetInteger() ) ) { rnd = gameLocal.random.RandomFloat() * file->GetNumAreas(); for( i = 0; i < file->GetNumAreas(); i++ ) { n = ( rnd + i ) % file->GetNumAreas(); if( file->GetArea( n ).flags & ( AREA_REACHABLE_WALK | AREA_REACHABLE_FLY ) ) { aas_pullPlayer.SetInteger( n ); } } } else { ShowWalkPath( origin, aas_pullPlayer.GetInteger(), AreaCenter( aas_pullPlayer.GetInteger() ) ); } }
/* ============ idAASLocal::ShowNearestCoverArea ============ */ void idAASLocal::ShowNearestCoverArea( const idVec3 &origin, int targetAreaNum ) const { int areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), AAS_AREA_REACHABLE_WALK, TravelFlagInvalidForTeam() ); idVec3 target = AreaCenter( targetAreaNum ); DrawCone( target, idVec3(0,0,1), 16.0f, colorYellow ); idAASCallback_FindCoverArea findCover( target ); idAASGoal goal; if ( FindNearestGoal( goal, areaNum, origin, TravelFlagInvalidForTeam(), findCover ) ) { DrawArea( goal.areaNum ); ShowWalkPath( areaNum, origin, goal.areaNum, goal.origin, TravelFlagForTeam(), TravelFlagWalkForTeam() ); DrawCone( goal.origin, idVec3( 0, 0, 1 ), 16.0f, colorWhite ); } }
/* ============ idAASLocal::ShowWalkPath ============ */ void idAASLocal::ShowWalkPath( const idVec3 &startOrigin, int goalAreaNum, const idVec3 &goalOrigin ) const { if ( file == NULL ) { return; } idPlayer *player = gameLocal.GetLocalPlayer(); if ( player == NULL ) { return; } idVec3 areaOrigin = startOrigin; int startAreaNum = PointReachableAreaNum( areaOrigin, DefaultSearchBounds(), AAS_AREA_REACHABLE_WALK, TravelFlagInvalidForTeam() ); PushPointIntoArea( startAreaNum, areaOrigin ); ShowWalkPath( startAreaNum, areaOrigin, goalAreaNum, goalOrigin, TravelFlagForTeam(), TravelFlagWalkForTeam() ); }
/* ============ 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 ); } }
/* ============ idAASLocal::Test ============ */ void idAASLocal::Test( const idVec3 &origin ) { int areaNum; idVec3 location; if ( file == NULL ) { return; } if ( GetAreaNumAndLocation( aas_locationMemory, origin, areaNum, location ) ) { } if ( GetAreaNumAndLocation( aas_showPath, origin, areaNum, location ) ) { ShowWalkPath( origin, areaNum, location ); } if ( GetAreaNumAndLocation( aas_showHopPath, origin, areaNum, location ) ) { ShowHopPath( origin, areaNum, location ); } if ( GetAreaNumAndLocation( aas_pullPlayer, origin, areaNum, location ) ) { int startAreaNum, travelTime; ShowWalkPath( origin, areaNum, location ); PullPlayer( origin, areaNum, location, startAreaNum, travelTime ); } else { UnFreezePlayer(); } if ( aas_randomPullPlayer.GetInteger() != 0 ) { RandomPullPlayer( origin, aas_randomPullPlayer.GetInteger() ); } if ( aas_showAreas.GetInteger() != 0 ) { ShowArea( origin, aas_showAreas.GetInteger() ); } if ( aas_showAreaNumber.GetInteger() != 0 ) { DrawArea( aas_showAreaNumber.GetInteger() ); } if ( ( aas_showNearestCoverArea.GetInteger() > 0 ) && ( aas_showNearestCoverArea.GetInteger() < file->GetNumAreas() ) ) { ShowNearestCoverArea( origin, aas_showNearestCoverArea.GetInteger() ); } if ( aas_showNearestInsideArea.GetBool() ) { ShowNearestInsideArea( origin ); } if ( aas_showWallEdges.GetInteger() != 0 ) { ShowWallEdges( origin, aas_showWallEdges.GetInteger(), aas_showWallEdgeNums.GetBool() ); } if ( aas_showPushIntoArea.GetBool() ) { ShowPushIntoArea( origin ); } if ( aas_showFloorTrace.GetBool() ) { ShowFloorTrace( origin ); } if ( GetAreaNumAndLocation( aas_showObstaclePVS, origin, areaNum, location ) ) { ShowObstaclePVS( areaNum ); } if ( aas_showManualReachabilities.GetBool() ) { ShowManualReachabilities(); } if ( aas_showFuncObstacles.GetBool() ) { ShowAASObstacles(); } if ( aas_showBadAreas.GetInteger() != 0 ) { ShowAASBadAreas( aas_showBadAreas.GetInteger() ); } }
/* ============ 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; }