unreal/AdventurePlayerController.cpp

146 lines
4.4 KiB
C++

// 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<AHexTile*> AAdventurePlayerController::Vision(int32 Radius)
{
TSet<AHexTile*> InRange = MapRef->BreadthFirstSearch(CurrentHex, Radius);
TArray<AHexTile*> 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<AHexTile*> 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<AMovementArrow>(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<AMapObject>(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<AMapObject> MapObjClass, AHexTile* HoveredTile)
{
AMapObject* SpawnedObj = World->SpawnActor<AMapObject>(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();
}