1 #using scripts\shared\array_shared;
2 #using scripts\shared\callbacks_shared;
3 #using scripts\shared\math_shared;
4 #using scripts\shared\system_shared;
5 #using scripts\shared\util_shared;
6 #using scripts\shared\weapons_shared;
7 #using scripts\shared\weapons\_weapons;
9 #using scripts\shared\bots\_bot;
10 #using scripts\shared\bots\bot_buttons;
12 #insert scripts\shared\shared.gsh;
14 #define TRACE_DISTANCE 128
16 #define TRAVERSAL_TIMEOUT 8
19 #define WALLRUN_JUMP_HEIGHT 40
21 #define WALLRUN_JUMP_VELOCITY 200
23 #define MANTLE_CHECK_HEIGHT 16
30 #define DOUBLEJUMP_V_UP 80
31 #define BOT_MIN_JUMP_JET 0.7
33 #define BOT_JUMP_ALIGN_DOT 0.94
39 zDelta = endNode.origin[2] - startNode.origin[2];
40 xyDist = Distance2D( startNode.origin, endNode.origin );
52 standingViewHeight = GetDvarFloat(
"player_standingViewHeight", 0 );
53 swimWaterHeight = standingViewHeight * GetDvarFloat(
"player_swimHeightRatio", 0 );
55 startWaterHeight = GetWaterHeight( startNode.origin );
56 startInWater = startWaterHeight != 0 && startWaterHeight > ( startNode.origin[2] + swimWaterHeight );
58 endWaterHeight = GetWaterHeight( endNode.origin );
59 endInWater = endWaterHeight != 0 && endWaterHEight > ( endNode.origin[2] + swimWaterHeight );
61 if ( IsWallrunNode( endNode ) )
65 else if ( startInWater && !endInWater )
69 else if ( startInWater && endInWater )
73 else if ( zDelta >= 0 )
77 else if ( zDelta < 0 )
84 self BotReleaseManualControl();
86 PrintLn(
"Bot ",
self.
name,
" can't handle traversal!" );
102 return !
self IsOnGround() ||
self IsWallRunning() ||
self IsDoubleJumping() ||
self IsMantling() ||
self IsSliding();
111 self endon(
"death" );
112 self endon(
"traversal_end" );
113 level endon(
"game_ended" );
117 self BotSetMoveAngleFromPoint( endNode.origin );
119 while (
self IsPlayerUnderWater() )
136 self endon(
"death" );
137 level endon(
"game_ended" );
138 self endon(
"traversal_end" );
140 self BotSetMoveAngleFromPoint( endNode.origin );
152 self endon(
"death" );
153 level endon(
"game_ended" );
154 self endon(
"traversal_end" );
158 ledgeTop = CheckNavMeshDirection( endNode.origin,
self.origin - endNode.origin, 128, 1 );
160 height = ledgeTop[2] -
self.origin[2];
168 dist = Distance2D(
self.origin, ledgeTop );
169 ledgeBottom = CheckNavMeshDirection(
self.origin, ledgeTop -
self.origin, dist +
BOT_RADIUS, 1 );
170 bottomDist = Distance2D(
self.origin, ledgeBottom );
173 if ( bottomDist <= dist )
185 speed =
self GetPlayerSpeed();
186 moveDist = t * speed2D;
188 if ( !moveDist || dist > moveDist )
194 self BotSetMoveMagnitude( dist / moveDist );
202 while( (
self.origin[2] +
BOT_HEIGHT ) < ledgeTop[2] )
207 self BotSetMoveMagnitude( 1 );
212 self endon(
"death" );
213 self endon(
"traversal_end" );
214 level endon(
"game_ended" );
219 fwd = ( endNode.origin[0] - startNode.origin[0], endNode.origin[1] - startNode.origin[1], 0 );
228 if (
result[
"surfacetype"] !=
"none" )
230 self BotSetMoveAngleFromPoint( endNode.origin );
240 dist = Distance2D( startNode.origin, endNode.origin );
241 height = startNode.origin[2] - endNode.origin[2];
243 gravity =
self GetPlayerGravity();
245 t = Sqrt( ( 2 * height ) / gravity );
249 if ( t * speed2D < dist )
252 ledgeTop = CheckNavMeshDirection( startNode.origin, endNode.origin - startNode.origin,
TRACE_DISTANCE, 1 );
254 bottomDist = dist - Distance2D( startNode.origin, ledgeTop );
255 ledgeBottom = CheckNavMeshDirection( endNode.origin, startNode.origin - endNode.origin, bottomDist, 1 );
257 meshDist = Distance2D( ledgeTop, ledgeBottom );
261 self thread
jump_to( endNode.origin );
266 self BotSetMoveAngleFromPoint( endNode.origin );
274 self endon(
"death" );
275 self endon(
"traversal_end" );
276 level endon(
"game_ended" );
281 wallNormal = GetNavMeshFaceNormal( endNode.origin, 30 );
282 wallNormal = VectorNormalize( ( wallNormal[0], wallNormal[1], 0 ) );
284 traversalDir = ( startNode.origin[0] - endNode.origin[0], startNode.origin[1] - endNode.origin[1], 0 );
286 cross = VectorCross( wallNormal, traversalDir );
288 runDir = VectorCross( wallNormal, cross );
290 self BotSetLookAngles( runDir );
292 self thread
jump_to( endNode.origin, vector );
299 self endon(
"death" );
300 self endon(
"traversal_end" );
301 level endon(
"game_ended" );
303 self waittill(
"wallrun_begin" );
308 self BotSetMoveAngle( runDir );
312 index =
self GetNodeIndexOnPath( startNode );
315 exitStartNode =
self GetNextTraversalNodeOnPath( index );
316 if ( isdefined( exitStartNode ) )
318 exitEndNode = GetOtherNodeInNegotiationPair( exitStartNode );
320 if ( isdefined( exitEndNode ) )
322 self thread
exit_wallrun( exitStartNode, exitEndNode, wallNormal, VectorNormalize( runDir ) );
329 self endon(
"death" );
330 self endon(
"traversal_end" );
331 level endon(
"game_ended" );
335 gravity =
self GetPlayerGravity();
339 tPeak = vUp / gravity;
343 fallDist = hPeak - endNode.origin[2];
347 tFall = Sqrt( fallDist / ( 0.5 * gravity ) );
357 exitDir = endNode.origin - startNode.origin;
358 dNormal = VectorDot( exitDir, wallNormal );
360 vNormal = dNormal / t;
377 endDir = endNode.origin -
self.origin;
378 endDist = VectorDot( endDir, runNormal );
382 dForward = ( vRun + vForward ) * t;
393 if ( endDist <= dForward )
395 jumpAngle = ( wallNormal * vNormal ) + ( runNormal * vForward );
397 if ( IsWallrunNode( endNode ) )
403 self BotSetLookAnglesFromPoint( endNode.origin );
404 self thread
jump_to( endNode.origin, jumpAngle );
413 self endon(
"death" );
414 self endon(
"traversal_end" );
415 level endon(
"game_ended" );
417 if ( isdefined( vector ) )
419 self BotSetMoveAngle( vector );
420 moveDir = VectorNormalize( ( vector[0], vector[1], 0 ) );
424 self BotSetMoveAngleFromPoint( target );
425 targetDelta = target -
self.origin;
426 moveDir = VectorNormalize( ( targetDelta[0], targetDelta[1], 0 ) );
429 velocity =
self GetVelocity( );
430 velocityDir = VectorNormalize( ( velocity[0], velocity[1], 0 ) );
441 while ( !
self IsOnGround() &&
442 !
self IsMantling() &&
443 !
self IsWallRunning() &&
448 if ( !isdefined( vector ) )
450 self BotSetMoveAngleFromPoint( target );
461 self endon(
"death" );
462 self endon(
"traversal_end" );
463 level endon(
"game_ended" );
465 while ( !
self IsMantling() )
467 self BotSetMoveAngleFromPoint( target );
475 velocity =
self GetVelocity();
477 targetDir = target -
self.origin;
478 targetDir = ( targetDir[0], targetDir[1], 0 );
481 if (
self.origin[2] > target[2] && VectorDot( velocity, targetDir ) <= 0 )
486 targetDist = Length( targetDir );
488 targetSpeed = Length( velocity );
490 if ( targetSpeed == 0 )
495 t = targetDist / targetSpeed;
497 gravity =
self GetPlayerGravity();
499 height =
self.origin[2] + velocity[2] * t - ( gravity * t * t * .5 );
501 return height >= ( target[2] + 32 );
506 velocity =
self GetVelocity();
508 speed2D = Distance2D( velocity, ( 0, 0, 0 ) );
518 self notify(
"watch_travesal_end" );
520 self endon(
"death" );
521 self endon(
"traversal_end" );
522 self endon(
"watch_travesal_end" );
523 level endon(
"game_ended" );
528 self waittill(
"acrobatics_end" );
535 self endon(
"death" );
536 self endon(
"traversal_end" );
537 self endon(
"watch_travesal_end" );
538 level endon(
"game_ended" );
540 while(
self IsPlayerSwimming() )
547 while( !
self IsPlayerSwimming() )
557 self endon(
"death" );
558 self endon(
"traversal_end" );
559 self endon(
"watch_travesal_end" );
560 level endon(
"game_ended" );
566 self BotRequestPath();
571 self notify(
"traversal_end" );
575 self BotLookForward();
576 self BotSetMoveMagnitude( 1 );
577 self BotReleaseManualControl();