//============================================================================= // AICommand_Crawler_LeapToWall //============================================================================= // //============================================================================= // Killing Floor 2 // Copyright (C) 2015 Tripwire Interactive LLC //============================================================================= class AICommand_Crawler_LeapToWall extends AICommand within KFAIController_ZedCrawler; var KFWallPathNode WallNode; var NavigationPoint StartLeapNode; var NavigationPoint EndLeapNode; var float JumpTime; /********************************************************************************************* * Initialization ********************************************************************************************* */ static function bool LeapToWall( KFAIController_ZedCrawler AI, NavigationPoint Start, NavigationPoint End, float InJumpTime ) { local AICommand_Crawler_LeapToWall Cmd; if( AI != None ) { Cmd = new(AI) Default.Class; if( Cmd != None ) { Cmd.StartLeapNode = Start; Cmd.EndLeapNode = End; Cmd.JumpTime = InJumpTime; AI.PushCommand(Cmd); return true; } } return false; } function Pushed() { super.Pushed(); DisableMeleeRangeEventProbing(); //MoveTimer = -1.0; //Pawn.ZeroMovementVariables(); StopAllLatentMovement(); // Abort move commands, too? GotoState('LeapingToWall'); } function Popped() { super.Popped(); EnableMeleeRangeEventProbing(); } /********************************************************************************************* * Notifications ********************************************************************************************* */ /** Prevent changing enemy while paused */ function bool CanChangeEnemy( Pawn NewEnemy ) { return false; } function bool NotifyLanded(vector HitNormal, Actor FloorActor ) { Pawn.SetPhysics(PHYS_Spider); return true; } function bool NotifyFallingHitWall(vector HitNormal, actor Wall) { return NotifyHitWall( HitNormal, Wall ); } function bool NotifyHitWall(vector HitNormal, actor HitActor) { if( !HitActor.bCanStepUpon ) { `warn( GetFuncName()$"() Wall "$HitActor$" bCanStepUpOn is FALSE" ); return false; } if( Pawn.Physics == PHYS_Falling ) { Pawn.SetPhysics( PHYS_Spider ); Pawn.SetBase( HitActor, HitNormal ); DisableNotifyHitWall(1.f); } return true; } /********************************************************************************************* * LeapToWall state ********************************************************************************************* */ state LeapingToWall { event BeginState( name PreviousStateName ) { Pawn.ZeroMovementVariables(); } function bool NotifyHitWall(vector HitNormal, actor HitActor) { if( !HitActor.bCanStepUpon ) { `warn( GetFuncName()$"() Wall "$HitActor$" bCanStepUpOn is FALSE" ); return false; } if( Pawn.Physics == PHYS_Falling ) { Pawn.SetPhysics( PHYS_Spider ); Pawn.SetBase( HitActor, HitNormal ); DisableNotifyHitWall(1.f); } return true; } function bool NotifyLanded(vector HitNormal, Actor FloorActor ) { if( HitNormal != vect(0,0,1) ) { Pawn.SetPhysics(PHYS_Spider); return true; } return false; } function bool DoWallLeap( Actor Target ) { //local Vector Suggested; local Vector JumpVel; if( (Pawn.Physics == PHYS_Walking || Pawn.Physics == PHYS_Spider) ) { MoveTimer = 2.f; //MyKFPawn.SuggestJumpVelocity( Suggested, Target.Location, Pawn.Location ); //JumpVel = ComputeTrajectoryByTime( Pawn.Location, Target.Location, 0.4f ); JumpVel = ComputeTrajectoryByTime( Pawn.Location, Target.Location, JumpTime ); MyKFPawn.Velocity = JumpVel; MoveTarget = Target; //MyKFPawn.Acceleration = vect( 0,0,0 ); MyKFPawn.SetPhysics( PHYS_Falling ); return true; } return false; } function DoLeap() { local vector JumpVel; JumpVel = ComputeTrajectoryByTime( Pawn.Location, EndLeapNode.Location, JumpTime ); Pawn.ZeroMovementVariables(); if( EndLeapNode.Location.Z > Pawn.Location.Z ) { JumpVel.Z *= 1.04f; } MyKFPawn.Velocity = JumpVel; MyKFPawn.SetPhysics( PHYS_Falling ); SetFocalPoint(vect(0,0,0)); Focus = EndLeapNode; } Begin: DoWallLeap( EndLeapNode ); WaitForLanding(); // 2.5.14 if( NavigationPoint(MoveTarget) != none ) { Pawn.SetAnchor( NavigationPoint(MoveTarget) ); } while( RouteCache.Length > 0 && RouteCache[ 0 ] == Pawn.Anchor ) { RouteCache_RemoveIndex(0); } // Pawn.SetPhysics( PHYS_Spider ); 2.9.2014 // Pawn.ResetDesiredRotation(); // SetFocalPoint(vect(0,0,0)); // Focus = none; Focus = RouteCache[0]; Pawn.ZeroMovementVariables(); Sleep( 0.35f ); // Note: Sleep( 0.1f ) results in weird snap rotation RecordLeapToWall(); Status = 'Success'; PopCommand( self ); }; state RotateToFocus { function PushedState() { super.PushedState(); AIActionStatus = "In RotateToFocus state"; } Begin: SetFocalPoint( vect(0,0,0) ); Focus = EndLeapNode; FinishRotation(); SetFocalPoint(Vect(0,0,0)); Focus = none; Pawn.ResetDesiredRotation(); PopState(); } DefaultProperties { bAllowedToAttack=false bIgnoreNotifies=true bIgnoreStepAside=true }