diff --git a/Content/BaseAIController_BP.uasset b/Content/BaseAIController_BP.uasset new file mode 100755 index 0000000..1699a07 Binary files /dev/null and b/Content/BaseAIController_BP.uasset differ diff --git a/Content/Marker_BP.uasset b/Content/Marker_BP.uasset new file mode 100755 index 0000000..73955a9 Binary files /dev/null and b/Content/Marker_BP.uasset differ diff --git a/Content/PlayerPawn_BP.uasset b/Content/PlayerPawn_BP.uasset index 208fe39..b9d4e98 100755 Binary files a/Content/PlayerPawn_BP.uasset and b/Content/PlayerPawn_BP.uasset differ diff --git a/Content/TestMap.umap b/Content/TestMap.umap index e4be275..2a80b90 100755 Binary files a/Content/TestMap.umap and b/Content/TestMap.umap differ diff --git a/Content/TestMap_BuiltData.uasset b/Content/TestMap_BuiltData.uasset index 672df80..d7d0282 100755 Binary files a/Content/TestMap_BuiltData.uasset and b/Content/TestMap_BuiltData.uasset differ diff --git a/PresidentsBrigade.sln b/PresidentsBrigade.sln index 30d3bf7..7478a2b 100755 --- a/PresidentsBrigade.sln +++ b/PresidentsBrigade.sln @@ -7,63 +7,81 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Engine", "Engine", "{94A6C6 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Games", "Games", "{8E2F6A87-1826-34F4-940C-CC23A48F9FE4}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UE4", "Intermediate\ProjectFiles\UE4.vcxproj", "{52E1ABCB-160A-496E-B0DF-3F45C156D01A}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PresidentsBrigade", "Intermediate\ProjectFiles\PresidentsBrigade.vcxproj", "{2FAC355B-B731-475C-8E0B-842BE82A5759}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PresidentsBrigade", "Intermediate\ProjectFiles\PresidentsBrigade.vcxproj", "{C841ECC2-1D1E-4BBB-AB40-4F3F71586811}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UE4", "Intermediate\ProjectFiles\UE4.vcxproj", "{74354AC2-E071-4234-87C9-5842B773C170}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Visualizers", "Visualizers", "{1CCEC849-CC72-4C59-8C36-2F7C38706D4C}" ProjectSection(SolutionItems) = preProject - ..\..\..\..\..\Program Files\Epic Games\UE_4.25\Engine\Extras\VisualStudioDebugging\UE4.natvis = ..\..\..\..\..\Program Files\Epic Games\UE_4.25\Engine\Extras\VisualStudioDebugging\UE4.natvis + D:\Games\Epic Games\UE_4.25\Engine\Extras\VisualStudioDebugging\UE4.natvis = D:\Games\Epic Games\UE_4.25\Engine\Extras\VisualStudioDebugging\UE4.natvis EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + DebugGame Editor|Android = DebugGame Editor|Android DebugGame Editor|Win32 = DebugGame Editor|Win32 DebugGame Editor|Win64 = DebugGame Editor|Win64 + DebugGame|Android = DebugGame|Android DebugGame|Win32 = DebugGame|Win32 DebugGame|Win64 = DebugGame|Win64 + Development Editor|Android = Development Editor|Android Development Editor|Win32 = Development Editor|Win32 Development Editor|Win64 = Development Editor|Win64 + Development|Android = Development|Android Development|Win32 = Development|Win32 Development|Win64 = Development|Win64 + Shipping|Android = Shipping|Android Shipping|Win32 = Shipping|Win32 Shipping|Win64 = Shipping|Win64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {52E1ABCB-160A-496E-B0DF-3F45C156D01A}.DebugGame Editor|Win32.ActiveCfg = BuiltWithUnrealBuildTool|Win32 - {52E1ABCB-160A-496E-B0DF-3F45C156D01A}.DebugGame Editor|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win32 - {52E1ABCB-160A-496E-B0DF-3F45C156D01A}.DebugGame|Win32.ActiveCfg = BuiltWithUnrealBuildTool|Win32 - {52E1ABCB-160A-496E-B0DF-3F45C156D01A}.DebugGame|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win32 - {52E1ABCB-160A-496E-B0DF-3F45C156D01A}.Development Editor|Win32.ActiveCfg = BuiltWithUnrealBuildTool|Win32 - {52E1ABCB-160A-496E-B0DF-3F45C156D01A}.Development Editor|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win32 - {52E1ABCB-160A-496E-B0DF-3F45C156D01A}.Development|Win32.ActiveCfg = BuiltWithUnrealBuildTool|Win32 - {52E1ABCB-160A-496E-B0DF-3F45C156D01A}.Development|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win32 - {52E1ABCB-160A-496E-B0DF-3F45C156D01A}.Shipping|Win32.ActiveCfg = BuiltWithUnrealBuildTool|Win32 - {52E1ABCB-160A-496E-B0DF-3F45C156D01A}.Shipping|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win32 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.DebugGame Editor|Win32.ActiveCfg = Invalid|Win32 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.DebugGame Editor|Win64.ActiveCfg = DebugGame_Editor|x64 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.DebugGame Editor|Win64.Build.0 = DebugGame_Editor|x64 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.DebugGame|Win32.ActiveCfg = DebugGame|Win32 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.DebugGame|Win32.Build.0 = DebugGame|Win32 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.DebugGame|Win64.ActiveCfg = DebugGame|x64 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.DebugGame|Win64.Build.0 = DebugGame|x64 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.Development Editor|Win32.ActiveCfg = Invalid|Win32 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.Development Editor|Win64.ActiveCfg = Development_Editor|x64 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.Development Editor|Win64.Build.0 = Development_Editor|x64 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.Development|Win32.ActiveCfg = Development|Win32 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.Development|Win32.Build.0 = Development|Win32 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.Development|Win64.ActiveCfg = Development|x64 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.Development|Win64.Build.0 = Development|x64 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.Shipping|Win32.ActiveCfg = Shipping|Win32 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.Shipping|Win32.Build.0 = Shipping|Win32 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.Shipping|Win64.ActiveCfg = Shipping|x64 - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811}.Shipping|Win64.Build.0 = Shipping|x64 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.DebugGame Editor|Android.ActiveCfg = Invalid|Win32 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.DebugGame Editor|Win32.ActiveCfg = Invalid|Win32 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.DebugGame Editor|Win64.ActiveCfg = DebugGame_Editor|x64 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.DebugGame Editor|Win64.Build.0 = DebugGame_Editor|x64 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.DebugGame|Android.ActiveCfg = Android_DebugGame|Win32 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.DebugGame|Android.Build.0 = Android_DebugGame|Win32 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.DebugGame|Win32.ActiveCfg = DebugGame|Win32 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.DebugGame|Win32.Build.0 = DebugGame|Win32 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.DebugGame|Win64.ActiveCfg = DebugGame|x64 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.DebugGame|Win64.Build.0 = DebugGame|x64 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.Development Editor|Android.ActiveCfg = Invalid|Win32 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.Development Editor|Win32.ActiveCfg = Invalid|Win32 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.Development Editor|Win64.ActiveCfg = Development_Editor|x64 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.Development Editor|Win64.Build.0 = Development_Editor|x64 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.Development|Android.ActiveCfg = Android_Development|Win32 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.Development|Android.Build.0 = Android_Development|Win32 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.Development|Win32.ActiveCfg = Development|Win32 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.Development|Win32.Build.0 = Development|Win32 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.Development|Win64.ActiveCfg = Development|x64 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.Development|Win64.Build.0 = Development|x64 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.Shipping|Android.ActiveCfg = Android_Shipping|Win32 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.Shipping|Android.Build.0 = Android_Shipping|Win32 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.Shipping|Win32.ActiveCfg = Shipping|Win32 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.Shipping|Win32.Build.0 = Shipping|Win32 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.Shipping|Win64.ActiveCfg = Shipping|x64 + {2FAC355B-B731-475C-8E0B-842BE82A5759}.Shipping|Win64.Build.0 = Shipping|x64 + {74354AC2-E071-4234-87C9-5842B773C170}.DebugGame Editor|Android.ActiveCfg = BuiltWithUnrealBuildTool|Win32 + {74354AC2-E071-4234-87C9-5842B773C170}.DebugGame Editor|Win32.ActiveCfg = BuiltWithUnrealBuildTool|Win32 + {74354AC2-E071-4234-87C9-5842B773C170}.DebugGame Editor|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win32 + {74354AC2-E071-4234-87C9-5842B773C170}.DebugGame|Android.ActiveCfg = BuiltWithUnrealBuildTool|Win32 + {74354AC2-E071-4234-87C9-5842B773C170}.DebugGame|Win32.ActiveCfg = BuiltWithUnrealBuildTool|Win32 + {74354AC2-E071-4234-87C9-5842B773C170}.DebugGame|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win32 + {74354AC2-E071-4234-87C9-5842B773C170}.Development Editor|Android.ActiveCfg = BuiltWithUnrealBuildTool|Win32 + {74354AC2-E071-4234-87C9-5842B773C170}.Development Editor|Win32.ActiveCfg = BuiltWithUnrealBuildTool|Win32 + {74354AC2-E071-4234-87C9-5842B773C170}.Development Editor|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win32 + {74354AC2-E071-4234-87C9-5842B773C170}.Development|Android.ActiveCfg = BuiltWithUnrealBuildTool|Win32 + {74354AC2-E071-4234-87C9-5842B773C170}.Development|Win32.ActiveCfg = BuiltWithUnrealBuildTool|Win32 + {74354AC2-E071-4234-87C9-5842B773C170}.Development|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win32 + {74354AC2-E071-4234-87C9-5842B773C170}.Shipping|Android.ActiveCfg = BuiltWithUnrealBuildTool|Win32 + {74354AC2-E071-4234-87C9-5842B773C170}.Shipping|Win32.ActiveCfg = BuiltWithUnrealBuildTool|Win32 + {74354AC2-E071-4234-87C9-5842B773C170}.Shipping|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {52E1ABCB-160A-496E-B0DF-3F45C156D01A} = {94A6C6F3-99B3-346E-9557-ABF9D4064DBD} - {C841ECC2-1D1E-4BBB-AB40-4F3F71586811} = {8E2F6A87-1826-34F4-940C-CC23A48F9FE4} + {74354AC2-E071-4234-87C9-5842B773C170} = {94A6C6F3-99B3-346E-9557-ABF9D4064DBD} + {2FAC355B-B731-475C-8E0B-842BE82A5759} = {8E2F6A87-1826-34F4-940C-CC23A48F9FE4} EndGlobalSection EndGlobal diff --git a/Source/PresidentsBrigade/BaseAIController.cpp b/Source/PresidentsBrigade/BaseAIController.cpp index cdded33..d1f2ed9 100755 --- a/Source/PresidentsBrigade/BaseAIController.cpp +++ b/Source/PresidentsBrigade/BaseAIController.cpp @@ -2,23 +2,128 @@ #include "BaseAIController.h" +#include "EngineUtils.h" #include "Util.h" #define LogInfo(Msg) Util::log_info(TEXT("ABaseAIController"), Msg) +#define LogError(Msg) Util::log_error(TEXT("ABasePawn"), Msg) void ABaseAIController::BeginPlay() { Super::BeginPlay(); - LogInfo("Hallo"); + + /* + * Initialize random stream. + */ + random.Initialize(FMath::Rand()); } void ABaseAIController::Tick(float delta) { Super::Tick(delta); - if (!move_to_location) - { - FVector destination(590, -620, 53); - MoveToLocation(destination); - move_to_location = true; - } -} \ No newline at end of file + + switch (current_state) + { + case state_t::init: + { + // Without this offset, the path finding to return to starting location will fail with + // invalid. I'm too sleepy to dig further. + const FVector offset(1.0, 1.0, 0); + starting_location = GetPawn()->GetActorLocation() + offset; + target_location = starting_location; + marker_locations = get_markers(); + + // Update state. + current_state = state_t::idle; + } + break; + case state_t::idle: + { + const bool should_wait = random.GetFraction() > .5; + const bool is_home = target_location == starting_location; + if (should_wait && is_home) + { + current_state = state_t::waiting; + } + else + { + target_location = is_home ? get_random_mark() : starting_location; + MoveToLocation(target_location); + current_state = state_t::moving; + } + } + break; + case state_t::moving: + if (move_completed) + { + move_completed = false; + current_state = state_t::waiting; + } + break; + case state_t::waiting: + waiting_time += delta; + if (waiting_time > wait_threshold) + { + waiting_time = 0; + current_state = state_t::idle; + } + break; + default: + /* + * Do nothing. + */ + break; + } +} + +void ABaseAIController::OnMoveCompleted(FAIRequestID request_id, const FPathFollowingResult& result) +{ + move_completed = true; +} + + +/** + * Helper function to load all the markers in the level. + */ +TArray ABaseAIController::get_markers() const +{ + TArray locations; + for (TActorIterator iterator(GetWorld()); iterator; ++iterator) + { + AActor* actor = *iterator; + if (actor && actor != this) + { + UClass* actor_class = actor->GetClass(); + + if (actor_class == marker_class) + { + locations.Add(actor->GetActorLocation()); + } + } + } + + if (locations.Num() == 0) + { + LogError("No markers"); + } + + return locations; +} + +/** + * Helper function for returning world location of randomly selected mark. + * + * @return World location vector of mark. + */ +FVector ABaseAIController::get_random_mark() const +{ + if (marker_locations.Num() == 0) + { + LogError("No markers"); + return FVector(); + } + + const int index = random.RandRange(0, marker_locations.Num() - 1); + return marker_locations[index]; +} + diff --git a/Source/PresidentsBrigade/BaseAIController.h b/Source/PresidentsBrigade/BaseAIController.h index 99882a8..e7cdea9 100755 --- a/Source/PresidentsBrigade/BaseAIController.h +++ b/Source/PresidentsBrigade/BaseAIController.h @@ -19,7 +19,56 @@ public: protected: virtual void BeginPlay() override; + virtual void OnMoveCompleted(FAIRequestID request_id, const FPathFollowingResult& result) override; + UPROPERTY(EditAnywhere, Category = "Movement") + UClass* marker_class; + + UPROPERTY(EditAnywhere, Category = "Movement") + float wait_threshold; private: - bool move_to_location = false; + enum state_t : uint8 { + init, + idle, + moving, + waiting + }; + + TArray get_markers() const; + FVector get_random_mark() const; + + /** + * List of marker locations. + */ + TArray marker_locations; + + /** + * Random number stream. + */ + FRandomStream random; + + /** + * Current state. + */ + state_t current_state = state_t::init; + + /** + * Move completed. + */ + bool move_completed; + + /** + * Starting location. + */ + FVector starting_location; + + /** + * Target location. + */ + FVector target_location; + + /** + * Time spent in waiting. + */ + float waiting_time; }; diff --git a/Source/PresidentsBrigade/BasePawn.h b/Source/PresidentsBrigade/BasePawn.h index 48fcf10..4127997 100755 --- a/Source/PresidentsBrigade/BasePawn.h +++ b/Source/PresidentsBrigade/BasePawn.h @@ -45,12 +45,13 @@ protected: UPROPERTY(EditAnywhere, Category="Player") UStaticMeshComponent* player_mesh; - UPROPERTY(EditAnywhere, Category="Player") + UPROPERTY(EditAnywhere, Category="Movement") UFloatingPawnMovement* movement_component; /** * Root component. */ + UPROPERTY(EditAnywhere, Category="Player") USceneComponent* root_component; /** diff --git a/Source/PresidentsBrigade/MarkerActor.cpp b/Source/PresidentsBrigade/MarkerActor.cpp index 9988919..b5b6c59 100755 --- a/Source/PresidentsBrigade/MarkerActor.cpp +++ b/Source/PresidentsBrigade/MarkerActor.cpp @@ -4,23 +4,16 @@ #include "MarkerActor.h" // Sets default values -AMarkerActor::AMarkerActor() +AMarkerActor::AMarkerActor(const FObjectInitializer &object_initializer): + AActor(object_initializer) { + marker = object_initializer.CreateDefaultSubobject(this, FName("Marker")); + marker->SetupAttachment(RootComponent); + marker->SetCollisionEnabled(ECollisionEnabled::NoCollision); + marker->SetGenerateOverlapEvents(false); + marker->SetCanEverAffectNavigation(false); + marker->SetHiddenInGame(true); + PrimaryActorTick.bCanEverTick = false; SetActorHiddenInGame(true); } - -// Called when the game starts or when spawned -void AMarkerActor::BeginPlay() -{ - Super::BeginPlay(); - -} - -// Called every frame -void AMarkerActor::Tick(float DeltaTime) -{ - Super::Tick(DeltaTime); - -} - diff --git a/Source/PresidentsBrigade/MarkerActor.h b/Source/PresidentsBrigade/MarkerActor.h index f819217..dfd46ff 100755 --- a/Source/PresidentsBrigade/MarkerActor.h +++ b/Source/PresidentsBrigade/MarkerActor.h @@ -13,14 +13,9 @@ class PRESIDENTSBRIGADE_API AMarkerActor : public AActor public: // Sets default values for this actor's properties - AMarkerActor(); + AMarkerActor(const FObjectInitializer &object_initializer); protected: - // Called when the game starts or when spawned - virtual void BeginPlay() override; - -public: - // Called every frame - virtual void Tick(float DeltaTime) override; - + UPROPERTY(EditAnywhere, Category="Tools") + UStaticMeshComponent* marker; }; diff --git a/todo.txt b/todo.txt index 09c4ff1..7b8fd4b 100644 --- a/todo.txt +++ b/todo.txt @@ -1,8 +1,11 @@ xAdd shooting -Add presidents car +xAdd presidents car xTakes damage xDies - Moves around + xMoves around + x Moves to markers on map + x Randomly chooses a marker + x Randomly moves after some time Add enemy cars Comes from off screen Attacks president car