void CNPC_Stalker::AddZigZagToPath(void) { // If already on a detour don't add a zigzag if (GetNavigator()->GetCurWaypointFlags() & bits_WP_TO_DETOUR) { return; } // If enemy isn't facing me or occluded, don't add a zigzag if (HasCondition(COND_ENEMY_OCCLUDED) || !HasCondition ( COND_ENEMY_FACING_ME )) { return; } Vector waypointPos = GetNavigator()->GetCurWaypointPos(); Vector waypointDir = (waypointPos - GetAbsOrigin()); // If the distance to the next node is greater than ZIG_ZAG_SIZE // then add a random zig/zag to the path if (waypointDir.LengthSqr() > ZIG_ZAG_SIZE) { // Pick a random distance for the zigzag (less that sqrt(ZIG_ZAG_SIZE) float distance = random->RandomFloat( 30, 60 ); // Get me a vector orthogonal to the direction of motion VectorNormalize( waypointDir ); Vector vDirUp(0,0,1); Vector vDir; CrossProduct( waypointDir, vDirUp, vDir); // Pick a random direction (left/right) for the zigzag if (random->RandomInt(0,1)) { vDir = -1 * vDir; } // Get zigzag position in direction of target waypoint Vector zigZagPos = GetAbsOrigin() + waypointDir * 60; // Now offset zigZagPos = zigZagPos + (vDir * distance); // Now make sure that we can still get to the zigzag position and the waypoint AIMoveTrace_t moveTrace1, moveTrace2; GetMoveProbe()->MoveLimit( NAV_GROUND, GetAbsOrigin(), zigZagPos, GetAITraceMask(), NULL, &moveTrace1); GetMoveProbe()->MoveLimit( NAV_GROUND, zigZagPos, waypointPos, GetAITraceMask(), NULL, &moveTrace2); if ( !IsMoveBlocked( moveTrace1 ) && !IsMoveBlocked( moveTrace2 ) ) { GetNavigator()->PrependWaypoint( zigZagPos, NAV_GROUND, bits_WP_TO_DETOUR ); } } }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ Vector CAI_BaseFlyingBot::VelocityToAvoidObstacles(float flInterval) { // -------------------------------- // Avoid banging into stuff // -------------------------------- trace_t tr; Vector vTravelDir = m_vCurrentVelocity*flInterval; Vector endPos = GetAbsOrigin() + vTravelDir; AI_TraceEntity( this, GetAbsOrigin(), endPos, GetAITraceMask()|CONTENTS_WATER, &tr ); if (tr.fraction != 1.0) { // Bounce off in normal Vector vBounce = tr.plane.normal * 0.5 * m_vCurrentVelocity.Length(); return (vBounce); } // -------------------------------- // Try to remain above the ground. // -------------------------------- float flMinGroundDist = MinGroundDist(); AI_TraceLine(GetAbsOrigin(), GetAbsOrigin() + Vector(0, 0, -flMinGroundDist), GetAITraceMask_BrushOnly()|CONTENTS_WATER, this, COLLISION_GROUP_NONE, &tr); if (tr.fraction < 1) { // Clamp veloctiy if (tr.fraction < 0.1) { tr.fraction = 0.1; } return Vector(0, 0, 50/tr.fraction); } return vec3_origin; }