Files
ProjectEleri/Source/ProjectEleri/Private/MyCharacter.cpp

367 lines
11 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "MyCharacter.h"
#include "EleriPlayerController.h"
#include "Kismet/GameplayStatics.h"
#include "Interface/ZoneInteractableInterface.h"
#include "EleriSaveGame.h"
#include "EleriGameInstance.h"
#include "PaperFlipbookComponent.h"
#include "Kismet/KismetMathLibrary.h"
#include "../GameObjects/WaterBall.h"
#include "ProjectEleri/GameObjects/BookActor.h"
#include "TimeOfDayManager.h"
#include "Components/PostProcessComponent.h"
#include "GameFramework/PawnMovementComponent.h"
#include "ProjectEleri/GameObjects/BenchmarkActor.h"
#include "ProjectEleri/System/MainBlueprintFunctionLibrary.h"
#include "ProjectEleri/UI/InteractionWidget.h"
#include "ProjectEleri/GameObjects/BookActor.h"
#include "ProjectEleri/GameObjects/BroomActor.h"
#include "Components/CapsuleComponent.h"
#include "Components/StatForgeComponent.h"
#include "GameFramework/SpringArmComponent.h"
#if WITH_EDITOR
void AMyCharacter::DisplayDebug(UCanvas* Canvas, const FDebugDisplayInfo& DebugDisplay, float& YL, float& YPos) {
Super::DisplayDebug(Canvas, DebugDisplay, YL, YPos);
}
#endif
// Sets default values
AMyCharacter::AMyCharacter()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
InteractableOverlapMesh = CreateDefaultSubobject<UBoxComponent>(FName("Box Collision"));
InteractableOverlapMesh->SetupAttachment(RootComponent);
InteractableOverlapMesh->SetRelativeLocation(FVector(0.0f, 0.0f, 33.33f));
InteractableOverlapMesh->SetRelativeScale3D(FVector(2.0f, 2.0f, 4.0f));
InteractableOverlapMesh->SetGenerateOverlapEvents(true);
StatForgeComponent = CreateDefaultSubobject<UStatForgeComponent>(TEXT("StatForgeComponent"));
}
bool AMyCharacter::IsEditor() const {
#if WITH_EDITOR
return true;
#else
return false;
#endif
}
// Called when the game starts or when spawned
void AMyCharacter::BeginPlay()
{
Super::BeginPlay();
if (GetCapsuleComponent()) {
CachedHalfHeight = GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight();
}
if (IsValid(GetWorld())) {
PlayerController = Cast<AEleriPlayerController>(UGameplayStatics::GetPlayerController(GetWorld(), 0));
}
if (IsValid(InteractableOverlapMesh)) {
InteractableOverlapMesh->OnComponentBeginOverlap.AddDynamic(this, &AMyCharacter::OnEnteredInteractableObject);
InteractableOverlapMesh->OnComponentEndOverlap.AddDynamic(this, &AMyCharacter::OnLeftInteractableObject);
}
CameraRef = GetComponentByClass<UCameraComponent>();
SpringArmRef = GetComponentByClass<USpringArmComponent>();
PlayerController->SetViewTarget(this);
SpringArmRef->TargetArmLength = DefaultZoom;
TSet<UActorComponent*> CameraComponents = GetComponents();
for (auto Comp : CameraComponents)
{
if (UPaperFlipbookComponent* SpriteComp = Cast<UPaperFlipbookComponent>(Comp))
{
if (SpriteComp->ComponentTags.Contains("CharacterSprite"))
{
CharacterSpriteComponent = SpriteComp;
}
}
}
FTransform BookTransform;
BookTransform.SetLocation(FVector(0,0,0));
BookTransform.SetRotation(FRotator(0,0,0).Quaternion());
BookTransform.SetScale3D(FVector::OneVector);
BookActor = GetWorld()->SpawnActor<ABookActor>(BookActorClass, BookTransform);
BookActor->AttachToComponent(CameraRef.Get(), FAttachmentTransformRules::KeepRelativeTransform);
BookActor->SetActorRelativeLocation(FVector(300,0,0));
BookActor->SetActorRelativeRotation(FRotator(0,90,0).Quaternion());
FTransform BroomTransform;
BroomTransform.SetLocation(FVector(0, 0, 0));
BroomTransform.SetRotation(FRotator(0, 0, 0).Quaternion());
BroomTransform.SetScale3D(FVector::OneVector);
BroomActor = GetWorld()->SpawnActor<ABroomActor>(BroomActorClass, BroomTransform);
BroomActor->AttachToComponent(RootComponent, FAttachmentTransformRules::SnapToTargetNotIncludingScale);
BroomActor->SetActorRelativeLocation(FVector(0, 0, -130));
SetNewCameraPitches(CameraPitchMin, CameraPitchMax);
}
bool AMyCharacter::ShouldSpawnFootprintVfx() const
{
bool bFlying = false;
bool bOnGround = false;
bool bBenchmarking = false;
if (PlayerController)
{
bFlying = PlayerController->IsFlying();
}
if (UPawnMovementComponent* MC = GetMovementComponent())
{
bOnGround = MC->Velocity.Z <= 0.1f && MC->Velocity.Z >= -0.1f;
}
if (ABenchmarkActor* BenchmarkActor = Cast<ABenchmarkActor>(UGameplayStatics::GetActorOfClass(GetWorld(), ABenchmarkActor::StaticClass())))
{
bBenchmarking = BenchmarkActor->bBenchmarkRunning;
}
return !bFlying && bOnGround && !bBenchmarking;
}
// Called every frame
void AMyCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (CurrentZoomTimer > 0.f) {
const float ZoomDelta = (NextZoomOffsetTarget * DeltaTime) / ZoomTime;
SpringArmRef->TargetArmLength += ZoomDelta;
CurrentZoomTimer -= DeltaTime;
UE_LOG(LogTemp, Warning, TEXT("Zooming in: ZoomDelta:%f"), ZoomDelta);
}
}
void AMyCharacter::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
}
void AMyCharacter::SetNewCameraPitches(float NewMinPitch, float NewMaxPitch)
{
PlayerCameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);
if (IsValid(PlayerCameraManager))
{
PlayerCameraManager->ViewPitchMin = NewMinPitch;
PlayerCameraManager->ViewPitchMax = NewMaxPitch;
}
}
FVector AMyCharacter::GetCameraWorldPosition() {
FVector CameraLocation;
FRotator CameraRotation;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(CameraLocation, CameraRotation);
return CameraLocation;
}
void AMyCharacter::ToggleBook(bool bOpen)
{
if (!IsValid(BookActor)) return;
float Aspect = 0.f;
if (GEngine && GEngine->GameViewport)
{
FVector2D Result = FVector2D(1, 1);
GEngine->GameViewport->GetViewportSize( Result);
Aspect = ((float)Result.X) / ((float)Result.Y);
}
if(Aspect == 0.f)
Aspect = ((float)GSystemResolution.ResX) / ((float)GSystemResolution.ResY);
BookActor->SetActorRelativeLocation(FVector(168.75f * Aspect, 0.f, 0.f));
BookActor->ToggleBook(bOpen);
/*if (UPostProcessComponent* PPComp = Cast<UPostProcessComponent>(FindComponentByTag(UPostProcessComponent::StaticClass(), FName("BookPP"))))
{
PPComp->bEnabled = bOpen;
}*/
}
// Called to bind functionality to input
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
void AMyCharacter::OnHarvestSeed_Implementation(class UItem* HarvestedItem)
{
}
void AMyCharacter::ZoomCamera(float CameraZoomAmount, float Time)
{
CurrentZoomTimer = Time;
ZoomTime = Time;
NextZoomOffsetTarget = CameraZoomAmount;
}
void AMyCharacter::ZoomBack(float Time) {
ZoomCamera(SpringArmRef->TargetArmLength - DefaultZoom, Time);
}
void AMyCharacter::ReturnCameraToPlayer() {
SpringArmRef->TargetArmLength = DefaultZoom;
PlayerController->SetViewTargetWithBlend(this, 0.5f);
}
void AMyCharacter::SetSaveableTagData(FGameplayTag Tag, int32 NewValue) {
SaveableTagData.Add(Tag, NewValue);
}
int32 AMyCharacter::GetSavableTagData(FGameplayTag Tag) const {
if (const int32* TagValue = SaveableTagData.Find(Tag)) {
return *TagValue;
}
return 0;
}
FActorSaveData AMyCharacter::RequestSave() {
FActorSaveData ActorData;
ActorData.ActorName = GetFName();
ActorData.Transform = GetActorTransform();
ActorData.SaveableTagData = SaveableTagData;
return ActorData;
}
void AMyCharacter::RequestLoad(FActorSaveData& Data) {
if (Data.ActorName != GetFName()) return;
SetActorTransform(Data.Transform);
SaveableTagData = Data.SaveableTagData;
ISaveableObjectInterface::Execute_OnDataLoaded(this);
}
void AMyCharacter::AttemptLookUp(float val, bool controllerInput)
{
AddControllerPitchInput(val);
Pitch = GetControlRotation().Pitch;
}
void AMyCharacter::OnEnteredInteractableObject(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& Hit)
{
if (IsValid(PlayerController) && !PlayerController->IsPaused()) {
if (PlayerController->IsDialogueOpen()) {
OnInteractBasedOnDoing();
}
else {
PlayerController->AddInteractableObject(OtherActor);
}
}
}
void AMyCharacter::OnLeftInteractableObject(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
PlayerController->RemoveInteractableObject(OtherActor);
}
void AMyCharacter::RotateTowardsCamera(FRotator CameraRot)
{
if (bIsWatering)
{
const FRotator ActorRot = GetActorRotation();
const FRotator FinalRot = FRotator(ActorRot.Pitch, CameraRot.Yaw, ActorRot.Roll);
SetActorRotation(UKismetMathLibrary::RInterpTo(ActorRot, FinalRot, UGameplayStatics::GetWorldDeltaSeconds(GetWorld()), 10.0f));
}
}
void AMyCharacter::HarvestSeed(class UItem* HarvestedItem)
{
}
AActor* AMyCharacter::GetClosestActor(TArray<AActor*> ActorSet) {
if (ActorSet.Num() <= 0) return nullptr;
AActor* Closest = ActorSet[0];
const float DistanceSqr = FVector::DistSquared(GetActorLocation(), Closest->GetActorLocation());
for (AActor* Actor : ActorSet) {
if (FVector::DistSquared(GetActorLocation(), Actor->GetActorLocation()) <= DistanceSqr) {
Closest = Actor;
}
}
return Closest;
}
void AMyCharacter::InitiateSave() {
if(UEleriGameInstance* GameInstance = Cast<UEleriGameInstance>(UGameplayStatics::GetGameInstance(GetWorld())))
GameInstance->SaveGame();
}
void AMyCharacter::InitiateLoad()
{
if (!IsValid(GetWorld())) return;
UEleriGameInstance* GameInstance = Cast<UEleriGameInstance>(UGameplayStatics::GetGameInstance(GetWorld()));
GameInstance->LoadGame();
}
void AMyCharacter::PlantSeed()
{
bIs_Planting = !bIs_Planting;
}
void AMyCharacter::BeginWatering()
{
if (!GetWorld()) return;
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
const FVector WaterBallSpawn = GetActorLocation();
WaterBallSpawned = Cast<AWaterBall>(GetWorld()->SpawnActor(WaterBallClass, &WaterBallSpawn, &FRotator::ZeroRotator, SpawnParams));
if (WaterBallSpawned)
{
const FAttachmentTransformRules AttachRules = FAttachmentTransformRules(EAttachmentRule::KeepRelative, false);
WaterBallSpawned->AttachToComponent(Cast<USceneComponent>(this->GetComponentByClass(USceneComponent::StaticClass())), AttachRules);
WaterBallSpawned->SetActorLocation(GetActorLocation() + (CameraRef->GetForwardVector() * 100.f) + (GetActorRightVector() * 200.f));
WaterBallSpawned->BeginAnimating();
}
}
void AMyCharacter::EndWatering() const
{
if (!GetWorld() || !WaterBallSpawned) return;
if (WaterBallSpawned)
{
WaterBallSpawned->EndAnimating();
}
}
void AMyCharacter::ThrowWaterBall() const
{
if (WaterBallSpawned)
{
WaterBallSpawned->ThrowBall();
}
}
void AMyCharacter::ToggleBroomActor(bool bActive)
{
bUseControllerRotationYaw = bActive;
if (GetCapsuleComponent()) {
GetCapsuleComponent()->SetCapsuleHalfHeight(bActive? CachedHalfHeight * 3 : CachedHalfHeight);
}
if (BroomActor) {
BroomActor->K2_BroomAnimationToggle(bActive);
}
}