From 237c056b30212fb853f4c3c3dce02c5787e70647 Mon Sep 17 00:00:00 2001 From: Maximilian Fajnberg Date: Mon, 24 Jan 2022 21:26:06 +0100 Subject: [PATCH] Base functionality for MapObject placement --- AdventureCameraPawn.cpp | 16 ++++++++++- AdventureCameraPawn.h | 6 +++- AdventureMap.cpp | 5 +++- AdventurePlayerController.cpp | 52 ++++++++++++++++++++++++++++------- AdventurePlayerController.h | 25 +++++++++++++++-- Clickable.cpp | 34 ----------------------- Clickable.h | 28 ------------------- HexTile.h | 6 ++-- 8 files changed, 93 insertions(+), 79 deletions(-) delete mode 100644 Clickable.cpp delete mode 100644 Clickable.h diff --git a/AdventureCameraPawn.cpp b/AdventureCameraPawn.cpp index 615bfaf..843e83d 100644 --- a/AdventureCameraPawn.cpp +++ b/AdventureCameraPawn.cpp @@ -28,6 +28,7 @@ AAdventureCameraPawn::AAdventureCameraPawn() ESAMinBoundSlope = -1 / ESASize; ESAMinBoundIntercept = 0 - (ESAMinBoundSlope * ESASize); + AutoPossessPlayer = EAutoReceiveInput::Player0; } // Called when the game starts or when spawned @@ -36,7 +37,7 @@ void AAdventureCameraPawn::BeginPlay() Super::BeginPlay(); ControllerRef = (AAdventurePlayerController*)UGameplayStatics::GetPlayerController(GetWorld(), 0); - // The Viewport properties are inaccurate right after BeginPlay, so we need to wait a short time before saving them here. + // Viewport properties not accurate on BeginPlay (must wait before accessing) FTimerHandle UnusedHandle; GetWorldTimerManager().SetTimer( UnusedHandle, this, &AAdventureCameraPawn::GetTheDamnViewport, 1, false); @@ -63,8 +64,21 @@ void AAdventureCameraPawn::SetupPlayerInputComponent(UInputComponent* PlayerInpu { PlayerInputComponent->BindAxis("Mouse X", this, &AAdventureCameraPawn::EdgeScrollSide); PlayerInputComponent->BindAxis("Mouse Y", this, &AAdventureCameraPawn::EdgeScrollVert); + + PlayerInputComponent->BindAxis("Move AD", this, &AAdventureCameraPawn::ScrollSide); + PlayerInputComponent->BindAxis("Move WS", this, &AAdventureCameraPawn::ScrollVert); } } +void AAdventureCameraPawn::ScrollSide(float AxisValue) +{ + float DeltaLoc = AxisValue * BaseScrollSpeed * 3; + AddActorLocalOffset(FVector(DeltaLoc, 0, 0)); +} +void AAdventureCameraPawn::ScrollVert(float AxisValue) +{ + float DeltaLoc = AxisValue * BaseScrollSpeed * -3; + AddActorLocalOffset(FVector(0, DeltaLoc, 0)); +} void AAdventureCameraPawn::EdgeScrollSide(float AxisValue) diff --git a/AdventureCameraPawn.h b/AdventureCameraPawn.h index 71bfae4..2295b2b 100644 --- a/AdventureCameraPawn.h +++ b/AdventureCameraPawn.h @@ -42,7 +42,7 @@ public: UPROPERTY() FVector AdvPawnLocationDelta; UPROPERTY(BlueprintReadWrite, Category = "Runtime") - bool bAdvPawnIsMoving; + bool bAdvPawnIsMoving = false; UPROPERTY(BlueprintReadWrite, Category = "Runtime") class AHexTile* SelectedHex; @@ -67,6 +67,10 @@ public: // Called to bind functionality to input virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; + UFUNCTION() + void ScrollSide(float AxisValue); + UFUNCTION() + void ScrollVert(float AxisValue); UFUNCTION(BlueprintCallable) void EdgeScrollSide(float AxisValue); UFUNCTION(BlueprintCallable) diff --git a/AdventureMap.cpp b/AdventureMap.cpp index 3e4aeac..554fbb6 100644 --- a/AdventureMap.cpp +++ b/AdventureMap.cpp @@ -118,6 +118,7 @@ TArray AAdventureMap::AStar(AHexTile* Start, AHexTile* Goal) // expand frontier & adjust path data for (AHexTile* Neighbor : Neighbors(Candidate)) { if (Neighbor->Distance(Candidate) > 1) { continue; } + if (!(Neighbor->bFree)) { continue; } if (Processed.Contains(Neighbor)) { continue; } bool bInToExamine = ToExamine.Contains(Neighbor); @@ -134,13 +135,15 @@ TArray AAdventureMap::AStar(AHexTile* Start, AHexTile* Goal) } } } - return LinkPath(Start, Goal); } TArray AAdventureMap::LinkPath(AHexTile* Start, AHexTile* Goal) { TArray Path; + + if (!IsValid(Goal->CameFrom)) { return Path; } + AHexTile* iPathNode = Goal; while (iPathNode != Start) { diff --git a/AdventurePlayerController.cpp b/AdventurePlayerController.cpp index c67e733..ad5f2cc 100644 --- a/AdventurePlayerController.cpp +++ b/AdventurePlayerController.cpp @@ -6,18 +6,27 @@ #include "HexTile.h" #include "AdventureCameraPawn.h" #include "AdventureCharacter.h" +#include "MapObject.h" AAdventurePlayerController::AAdventurePlayerController() { PrimaryActorTick.bCanEverTick = true; PrimaryActorTick.bStartWithTickEnabled = true; - + AutoReceiveInput = EAutoReceiveInput::Player0; } void AAdventurePlayerController::BeginPlay() { Super::BeginPlay(); World = GetWorld(); + HoveredHex = CurrentHex; +} +// Called every frame +void AAdventurePlayerController::Tick(float DeltaTime) +{ + Super::Tick(DeltaTime); + + if (bInPlacementMode) { FitOnGrid(PlaceObj); } } void AAdventurePlayerController::SetupInputComponent() @@ -26,18 +35,41 @@ void AAdventurePlayerController::SetupInputComponent() Super::SetupInputComponent(); // This is initialized on startup, you can go straight to binding - // InputComponent->BindAction("LeftClick", IE_Pressed, this, &AAdventurePlayerController::AdvClick); + InputComponent->BindAction("LeftClick", IE_Pressed, this, &AAdventurePlayerController::LeftClick); + InputComponent->BindAction("DebugAlt", IE_Pressed, this, &AAdventurePlayerController::TogglePlacing); // Change binding eventually } -void AAdventurePlayerController::AdvClick() +void AAdventurePlayerController::LeftClick() { - FHitResult Hit; - GetHitResultUnderCursor(ECollisionChannel::ECC_Vehicle,false,Hit); + if (bInPlacementMode) { PlaceObject(PlaceObjClass, HoveredHex); } +} - if (IsValid(Hit.GetActor())) - { - AHexTile* HitHex = (AHexTile*)Hit.GetActor(); - // MapRef->FindPathAStar(CurrentHex, HitHex); - // UE_LOG(LogTemp, Warning, TEXT("%d"), HitHex->Index); +void AAdventurePlayerController::TogglePlacing() +{ + bInPlacementMode = !bInPlacementMode; + if (bInPlacementMode) { + PlaceObj = World->SpawnActor(PlaceObjClass, FTransform()); } + else { if (IsValid(PlaceObj)) { PlaceObj->Destroy(); } } +} + +void AAdventurePlayerController::FitOnGrid(AMapObject* MapObject) +{ + if (!IsValid(HoveredHex)) { return; } + if (HoveredHex->bFree) { + MapObject->SetActorLocation(FVector(HoveredHex->GetActorLocation())); + } +} + +// called from BP; generally takes the Hex under the player cursor as argument +void AAdventurePlayerController::PlaceObject(TSubclassOf MapObjClass, AHexTile* OnHex) +{ + // spawn this Actor at World location of Origin Hex; + AMapObject* SpawnedObj = World->SpawnActor(MapObjClass, FTransform(OnHex->GetActorTransform().GetLocation())); + // Origin = OnHex; + SpawnedObj->Origin = OnHex; + // set Hexes to bOccupied according to BlockVectors; + OnHex->bFree = false; + // set bPlacementMode = false; + // } \ No newline at end of file diff --git a/AdventurePlayerController.h b/AdventurePlayerController.h index f8cb075..4fdd63a 100644 --- a/AdventurePlayerController.h +++ b/AdventurePlayerController.h @@ -11,7 +11,7 @@ class AAdventureMap; class AHexTile; class AAdventureCameraPawn; class AAdventureCharacter; - +class AMapObject; /** * */ @@ -23,6 +23,7 @@ class FRAY_API AAdventurePlayerController : public APlayerController public: AAdventurePlayerController(); +// General UPROPERTY() UWorld* World; UPROPERTY() @@ -31,11 +32,31 @@ public: AHexTile* SpawnHex; UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Runtime") AHexTile* CurrentHex; + UPROPERTY(BlueprintReadWrite, EditAnywhere) + AHexTile* HoveredHex; + UFUNCTION(BlueprintCallable) + void LeftClick(); protected: virtual void BeginPlay() override; virtual void SetupInputComponent() override; public: - void AdvClick(); + +// Object Placement + UPROPERTY(BlueprintReadWrite, VisibleAnywhere) + bool bInPlacementMode; + UPROPERTY(BlueprintReadWrite, EditAnywhere) + TSubclassOf PlaceObjClass; + UPROPERTY(BlueprintReadWrite, VisibleAnywhere) + AMapObject* PlaceObj; + UFUNCTION(BlueprintCallable) + void TogglePlacing(); + UFUNCTION(BlueprintCallable) + void FitOnGrid(AMapObject* MapObject); + UFUNCTION() + void PlaceObject(TSubclassOf MapObjClass, AHexTile* OnHex); + + // Called every frame + virtual void Tick(float DeltaTime) override; }; diff --git a/Clickable.cpp b/Clickable.cpp deleted file mode 100644 index 45ba5b3..0000000 --- a/Clickable.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - - -#include "Clickable.h" - -// Sets default values for this component's properties -UClickable::UClickable() -{ - // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features - // off to improve performance if you don't need them. - PrimaryComponentTick.bCanEverTick = true; - - // ... -} - - -// Called when the game starts -void UClickable::BeginPlay() -{ - Super::BeginPlay(); - - // ... - -} - - -// Called every frame -void UClickable::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) -{ - Super::TickComponent(DeltaTime, TickType, ThisTickFunction); - - // ... -} - diff --git a/Clickable.h b/Clickable.h deleted file mode 100644 index 9fb69f9..0000000 --- a/Clickable.h +++ /dev/null @@ -1,28 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#pragma once - -#include "CoreMinimal.h" -#include "Components/ActorComponent.h" -#include "Clickable.generated.h" - - -UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) ) -class FRAY_API UClickable : public UActorComponent -{ - GENERATED_BODY() - -public: - // Sets default values for this component's properties - UClickable(); - -protected: - // Called when the game starts - virtual void BeginPlay() override; - -public: - // Called every frame - virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; - - -}; diff --git a/HexTile.h b/HexTile.h index de5ea88..1465061 100644 --- a/HexTile.h +++ b/HexTile.h @@ -49,8 +49,6 @@ public: int32 MoveCost = 1; UPROPERTY(BlueprintReadWrite, VisibleInstanceOnly, Category = "Movement") AHexTile* CameFrom; - UPROPERTY(VisibleInstanceOnly, Category = "Movement") - int32 CostSoFar = 0; UPROPERTY() int32 FCost; UPROPERTY() @@ -58,6 +56,10 @@ public: UPROPERTY() int32 HCost; + // MapObject Placement + UPROPERTY(BlueprintReadWrite, VisibleAnywhere) + bool bFree = true; + FORCEINLINE bool operator == (const AHexTile &Other) { if (this->Q == Other.Q && this->R == Other.R) { return true; }