//============================================================================= // AIPluginStuckFix //============================================================================= // A proxy/parent class for all specific Stuck implementations //============================================================================= // Killing Floor 2 // Copyright (C) 2015 Tripwire Interactive LLC //============================================================================= class AIPluginStuckFix extends AITickablePlugin within BaseAIController native(Plugin) dependson(NavigationPath, AIPluginMovement) abstract; struct native FixStuckRequest { var native MoveParameters MoveParams; var float AcceptableDistance; var vector DestOffset; //var vector MidPointOffset; /** a struct type with union inside representing move destination. It seems * ok to have a native only access to it - script will only be able to modify means * of execution, but not destination itself. */ var native MoveRequestDestination Destination; //var native NavigationPath PreComputedPath; var EActionPriority Priority; var const object Observer; var bool bFinalApproach; var int QueryID; structcpptext { FFixStuckRequest() { appMemzero(this, sizeof(FFixStuckRequest)); Reset(); } FFixStuckRequest(FFixStuckRequest* pOther) { if(pOther != NULL) { appMemCopy(*this, *pOther); } else { appMemzero(this, sizeof(FFixStuckRequest)); Reset(); } } FString GetDescription() const; void Reset() { MoveParams.Reset(); AcceptableDistance=0.0f; Destination.Reset(); Priority = AP_Invalid; bFinalApproach = FALSE; Observer = NULL; } } }; var FixStuckRequest MoveRequest; var const public{protected} EActionPriority ActionPriority; var const public{private} EActionPriority MovementLock; var const transient bool bObserverNotified; var const transient bool bDontNotifyObserver; var transient bool bDontRestartByKismet; cpptext { UBOOL IsMovementLocked(const EActionPriority Priority = AP_Logic) const // AP_Locic, i.e. AP_Invalid + 1. { return MovementLock >= Priority; } EActionPriority GetMovementLock() const { return (EActionPriority)MovementLock; } UBOOL CanAcceptNewMoveRequest(EActionPriority NewRequestPriority) const { return NewRequestPriority >= ActionPriority; } FORCEINLINE EActionPriority GetActionPriority() const { return (EActionPriority)ActionPriority; } FVector GetDestination(struct FFixStuckRequest& Request) const { return Request.Destination.GetPosition(); } } /** overrideable only in native code (no-exported as virtual) */ function bool StuckFixToPointRequest(vector InDestLocation, EActionPriority CommandPriority, optional object ActionObserver, optional bool bStopAtEnd=true, optional bool bStickToNavmesh = true, optional float AcceptableDistance, optional Actor RotateAtEndToMatch); function bool StuckFixToActorRequest(Actor inPawnGoal, EActionPriority CommandPriority, optional object ActionObserver, optional bool bInAllowedToFire=true, optional float AcceptableDistance, optional vector DestOffset, optional vector MidPointOffset, optional bool bDynamicMidPoint, optional bool bStopAtEnd=true, optional bool bStickToNavmesh=true); event bool AbortMove(bool bNewRequest); /** * @param bNewRequest if set to false (default) then if there was a move * task paused while lock was being set, then this task will be resumed. * If true, it will not. This param makes sense only for bLock == true */ function SetMovementLock(bool bLock, optional EActionPriority Priority = AP_Logic, optional bool bNewRequest); function protected Success(); function protected Failure(); /** Script interface to get location of destination point from given MovementRequest. * no-exported to make inline. */ final native noexport function vector GetDestination(out MovementRequest Request) const; final function EMoveRequestDestinationType GetDestinationType() { return MoveRequest.Destination.Type; } function StopMovement() { //@todo fill it! } /** Called from native code during latent movement when current move is considered unreachable */ function bool MoveUnreachable( Vector AttemptedDest, Actor AttemptedTarget ) { if( AttemptedTarget != none ) { `AILog( GetFuncName()$" AttemptedTarget: "$AttemptedTarget, 'PathWarning' ); } return false; } state Succeeding `DEBUGSTATE { Begin: `AILog("Moving - END:"@GetStateName(), 'Move'); Success(); GotoState( 'Idling' ); } state Failing `DEBUGSTATE { Begin: `AILog("Moving - END:"@GetStateName(), 'Move'); Failure(); GotoState( 'Idling' ); } /* this state does nothing. It's here to leave other states when move is aborted, * and to indicate that it happened */ state Aborting `DEBUGSTATE { Begin: `AILog("Moving - Aborted", 'Move'); //AbortMove(false); StopMovement(); GotoState( 'Idling' ); } /* this state does nothing. It's here to leave other states when move is aborted, * and to indicate that it happened */ state Idling `DEBUGSTATE { Begin: `AILog("Idling", 'Move'); StopMovement(); } defaultproperties { // mz> this change is a little bit hacky and will need further changes. AnimSys accepts path success if destination to cover < 150.0f; //MinimumSuccessDistance=8100.0f //90 units //MinimumSuccessDistance=160.0f //90 units }