// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. #pragma once #include "AITypes.h" #include "GameFramework/Pawn.h" #include "GenericTeamAgentInterface.h" #include "FunctionalAITest.generated.h" class AFunctionalAITest; DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FFunctionalTestAISpawned, AAIController*, Controller, APawn*, Pawn); USTRUCT() struct FAITestSpawnInfo { GENERATED_USTRUCT_BODY() /** Determines AI to be spawned */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=AISpawn) TSubclassOf PawnClass; /** class to override default pawn's controller class. If None the default will be used*/ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=AISpawn) TSubclassOf ControllerClass; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=AISpawn) FGenericTeamId TeamID; /** if set will be applied to spawned AI */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=AISpawn) class UBehaviorTree* BehaviorTree; /** Where should AI be spawned */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=AISpawn) AActor* SpawnLocation; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=AISpawn, meta=(UIMin=1, ClampMin=1)) int32 NumberToSpawn; /** delay between consecutive spawn attempts */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AISpawn, meta = (UIMin = 0, ClampMin = 0)) float SpawnDelay; /** Gets filled owning spawn set upon game start */ FName SpawnSetName; FAITestSpawnInfo() : NumberToSpawn(1) {} FORCEINLINE bool IsValid() const { return PawnClass != NULL && SpawnLocation != NULL; } bool Spawn(AFunctionalAITest* AITest) const; }; USTRUCT() struct FPendingDelayedSpawn : public FAITestSpawnInfo { GENERATED_USTRUCT_BODY() uint32 NumberToSpawnLeft; float TimeToNextSpawn; bool bFinished; FPendingDelayedSpawn() : NumberToSpawnLeft(uint32(-1)), TimeToNextSpawn(FLT_MAX), bFinished(true) {} FPendingDelayedSpawn(const FAITestSpawnInfo& Source); void Tick(float TimeDelta, AFunctionalAITest* AITest); }; USTRUCT() struct FAITestSpawnSet { GENERATED_USTRUCT_BODY() /** what to spawn */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=AISpawn) TArray SpawnInfoContainer; /** give the set a name to help identify it if need be */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=AISpawn) FName Name; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=AISpawn) uint32 bEnabled:1; /** location used for spawning if spawn info doesn't define one */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AISpawn) AActor* FallbackSpawnLocation; FAITestSpawnSet() : bEnabled(true) {} }; UCLASS(Blueprintable, MinimalAPI) class AFunctionalAITest : public AFunctionalTest { GENERATED_UCLASS_BODY() protected: UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=AITest) TArray SpawnSets; UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = AITest, meta = (UIMin = "0.0")) float SpawnLocationRandomizationRange; UPROPERTY(BlueprintReadOnly, Category=AITest) TArray SpawnedPawns; UPROPERTY(BlueprintReadOnly, Category = AITest) TArray PendingDelayedSpawns; int32 CurrentSpawnSetIndex; FString CurrentSpawnSetName; /** Called when a single AI finished spawning */ UPROPERTY(BlueprintAssignable) FFunctionalTestAISpawned OnAISpawned; /** Called when a all AI finished spawning */ UPROPERTY(BlueprintAssignable) FFunctionalTestEventSignature OnAllAISPawned; uint32 bSingleSetRun:1; public: UFUNCTION(BlueprintCallable, Category = "Development") virtual bool IsOneOfSpawnedPawns(AActor* Actor); // AActor interface begin virtual void BeginPlay() override; virtual void Tick(float DeltaSeconds) override; // AActor interface end virtual bool StartTest(const TArray& Params = TArray()) override; virtual bool WantsToRunAgain() const override; virtual void GatherRelevantActors(TArray& OutActors) const override; virtual void CleanUp() override; virtual FString GetAdditionalTestFinishedMessage(EFunctionalTestResult::Type TestResult) const override; virtual FString GetReproString() const override; void AddSpawnedPawn(APawn& SpawnedPawn); FVector GetRandomizedLocation(const FVector& Location) const; protected: void KillOffSpawnedPawns(); void ClearPendingDelayedSpawns(); };