#pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "Containers/Map.h" #include "HexVector.h" #include "AdventureMap.generated.h" class AHexTile; class AStarFog; class AMapObject; class AAdventurePlayerController; UCLASS() class FRAY_API AAdventureMap : public AActor { GENERATED_BODY() public: // Sets default values for this actor's properties AAdventureMap(); UPROPERTY() UWorld* World; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Config") TSubclassOf BaseTileClass; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Config") TSubclassOf BaseFogClass; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Config") int32 GridSize = 60; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Config") int32 TileSize = 100; UPROPERTY(VisibleAnywhere, BlueprintReadWrite) AAdventurePlayerController* PCRef; UFUNCTION(BlueprintCallable, Category = "Generation") void MakeGrid(); UPROPERTY(BlueprintReadOnly, Category = "Generation") bool bHexGridReady; UPROPERTY(BlueprintReadOnly, Category = "Generation") TArray Grid; UFUNCTION(BlueprintCallable, Category = "Utility") int32 GridIndex(int32 q, int32 r); UFUNCTION(BlueprintCallable, Category = "Utility") AHexTile* RandomHex(); // Cardinal direction vectors UPROPERTY(BlueprintReadOnly, VisibleAnywhere) //diag FHexVector N = FHexVector(1, -2); // UPROPERTY(BlueprintReadOnly, VisibleAnywhere) FHexVector NNE = FHexVector(1, -1); UPROPERTY(BlueprintReadOnly, VisibleAnywhere) //diag FHexVector ENE = FHexVector(2, -1); // UPROPERTY(BlueprintReadOnly, VisibleAnywhere) FHexVector E = FHexVector(1, 0); UPROPERTY(BlueprintReadOnly, VisibleAnywhere) //diag FHexVector ESE = FHexVector(1, 1); // UPROPERTY(BlueprintReadOnly, VisibleAnywhere) FHexVector SSE = FHexVector(0, 1); UPROPERTY(BlueprintReadOnly, VisibleAnywhere) //diag FHexVector S = FHexVector(-1, 2); // UPROPERTY(BlueprintReadOnly, VisibleAnywhere) FHexVector SSW = FHexVector(-1, 1); UPROPERTY(BlueprintReadOnly, VisibleAnywhere) //diag FHexVector WSW = FHexVector(-2, 1); // UPROPERTY(BlueprintReadOnly, VisibleAnywhere) FHexVector W = FHexVector(-1, 0); UPROPERTY(BlueprintReadOnly, VisibleAnywhere) //diag FHexVector WNW = FHexVector(-1, -1); // UPROPERTY(BlueprintReadOnly, VisibleAnywhere) FHexVector NNW = FHexVector(0, -1); UPROPERTY(BlueprintReadOnly, VisibleAnywhere) TArray UnitVectors; UPROPERTY(BlueprintReadOnly, VisibleAnywhere) TArray DiagonalUnitVectors; UFUNCTION(BlueprintCallable, Category = "Utility") FHexVector UnitDiagFromUnitNB(FHexVector InVecA, FHexVector InVecB); UFUNCTION(BlueprintCallable, Category = "Utility") bool DiagIsReachable(AHexTile* InStart, FHexVector InDiagUnitVec); UFUNCTION(BlueprintCallable, Category = "Utility") float Lerp(int32 a, int32 b, float t); UFUNCTION(BlueprintCallable, Category = "Utility") FHexVector AxialRound(float q, float r); UFUNCTION(BlueprintCallable, Category = "Utility") TArray Neighbors(AHexTile* OfHex, bool bFreeOnly); UFUNCTION(BlueprintCallable, Category = "Utility") TArray FreeDiagonals(AHexTile* OfHex); UFUNCTION(BlueprintCallable, Category = "Utility") TSet BreadthFirstSearch(AHexTile* Start, int32 Radius); UFUNCTION(BlueprintCallable, Category = "Runtime") TArray FindPathAStar(AHexTile* Start, AHexTile* Goal, bool bDiags); UFUNCTION(BlueprintCallable, Category = "Runtime") TArray ShortcutAStar(TArray Path); // considering a MapObjectManager class or moving pathfinding & search to PlayerController UPROPERTY(BlueprintReadWrite, EditAnywhere) TMap MapObjects; UPROPERTY(BlueprintReadOnly) TMap MapObjectsByID; UPROPERTY(BlueprintReadWrite, VisibleAnywhere) int32 IncID = -1; protected: // Called when the game starts or when spawned virtual void BeginPlay() override; }; // only used for an experimental implementation of A* template struct TPriorityQueueNode { InElementType Element; float Priority; TPriorityQueueNode() { } TPriorityQueueNode(InElementType InElement, float InPriority) { Element = InElement; Priority = InPriority; } bool operator<(const TPriorityQueueNode Other) const { return Priority < Other.Priority; } }; template class TPriorityQueue { public: TPriorityQueue() { Array.Heapify(); } public: // Always check if IsEmpty() before Pop-ing! InElementType Pop() { TPriorityQueueNode Node; Array.HeapPop(Node); return Node.Element; } TPriorityQueueNode PopNode() { TPriorityQueueNode Node; Array.HeapPop(Node); return Node; } void Push(InElementType Element, float Priority) { Array.HeapPush(TPriorityQueueNode(Element, Priority)); } bool IsEmpty() const { return Array.Num() == 0; } public: // make private later on TArray> Array; };