// Fill out your copyright notice in the Description page of Project Settings. #include "AdventurePlayerController.h" #include "AdventureMap.h" #include "HexTile.h" #include "AdventureCameraPawn.h" #include "AdventureCharacter.h" #include "MapObject.h" #include "MovementArrow.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() { // Always call this. Super::SetupInputComponent(); // This is initialized on startup, you can go straight to binding InputComponent->BindAction("LeftClick", IE_Pressed, this, &AAdventurePlayerController::LeftClick); InputComponent->BindAction("DebugAlt", IE_Pressed, this, &AAdventurePlayerController::EnablePlacing); // Change binding eventually InputComponent->BindAction("DebugAlt", IE_Released, this, &AAdventurePlayerController::DisablePlacing); // Change binding eventually } void AAdventurePlayerController::LeftClick() { if (IsValid(HoveredHex)) { if (!bInPlacementMode) { } else { PlaceObject(PlaceObjClass, HoveredHex); } } else { return; } } TArray AAdventurePlayerController::Vision(int32 Radius) { TSet InRange = MapRef->BreadthFirstSearch(CurrentHex, Radius); TArray Results; for (auto& Hex : InRange) { if (Hex->Distance(CurrentHex) == Radius) { for (int32 i = 1; i <= Radius; i++) { float t = 1.0f / Radius * i; FHexVector Sample; Sample = MapRef->AxialRound(MapRef->Lerp(CurrentHex->Q, Hex->Q, t), MapRef->Lerp(CurrentHex->R, Hex->R, t)); AHexTile* SampleHex = MapRef->Grid[MapRef->GridIndex(Sample.Q, Sample.R)]; Results.Add(SampleHex); if (!ExploredHexes.Contains(SampleHex)) { ExploredHexes.Add(Hex); } if (!SampleHex->bFree) { break; } } } } return Results; } void AAdventurePlayerController::MarkPath(TArray Path) { if (Path.IsEmpty()) { return; } else if (!IsValid(Path[0])) { return; } else if (CurrentHex->Distance(Path[0])>1) { return; } FHexVector DirA = FHexVector(Path[0]->Q - CurrentHex->Q, Path[0]->R - CurrentHex->R); FHexVector DirB; for (int32 i = 0; i < Path.Num() - 1; i++) { DirB = FHexVector(Path[i + 1]->Q - Path[i]->Q, Path[i + 1]->R - Path[i]->R); AMovementArrow* Arrow = World->SpawnActor(MoveArrowClass, Path[i]->GetActorTransform()); Arrow->MapRef = MapRef; Arrow->SetVariant(DirA, DirB); PathArrows.Add(Arrow); DirA = DirB; } } void AAdventurePlayerController::ClearPath() { for (AMovementArrow* Arrow : PathArrows) { Arrow->Destroy(); } PathArrows.Empty(); } void AAdventurePlayerController::EnablePlacing() { bInPlacementMode = true; PlaceObj = World->SpawnActor(PlaceObjClass, FTransform()); } void AAdventurePlayerController::DisablePlacing() { bInPlacementMode = false; // if (IsValid(PlaceObj)) { PlaceObj->Destroy(); } } void AAdventurePlayerController::FitOnGrid(AMapObject* MapObject) { if (!IsValid(HoveredHex)) { return; } if (HoveredHex->bFree) { MapObject->SetActorLocation(FVector(HoveredHex->GetActorLocation())); } } // To-Do: factor out core functionality to a seperate (more neutral) class like AdventureMap. void AAdventurePlayerController::PlaceObject(TSubclassOf MapObjClass, AHexTile* HoveredTile) { AMapObject* SpawnedObj = World->SpawnActor(MapObjClass, FTransform(HoveredTile->GetActorTransform().GetLocation())); SpawnedObj->MapRef = MapRef; SpawnedObj->Origin = HoveredTile; SpawnedObj->bPlaced = true; HoveredTile->bFree = false; HoveredTile->MapObject = SpawnedObj; MapRef->MapObjects.Add(HoveredTile, SpawnedObj); MapRef->IncID++; SpawnedObj->ID = MapRef->IncID; MapRef->MapObjectsByID.Add(MapRef->IncID, SpawnedObj); SpawnedObj->Occupy(); }