Files
ProjectEleri/Source/ProjectEleri/Private/EleriPlayerController.cpp

1206 lines
40 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "EleriPlayerController.h"
#include "EnhancedInputComponent.h"
#include "Kismet/KismetMathLibrary.h"
#include "GameFramework/Character.h"
#include "EnhancedInputSubsystems.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Interface/ZoneInteractableInterface.h"
#include "ProjectEleri/System/MainBlueprintFunctionLibrary.h"
#include "ProjectEleri/Components/MoveActorsComponent.h"
#include "../GameObjects/RemovableStaticMeshActor.h"
#include "Components/WidgetComponent.h"
#include "Kismet/GameplayStatics.h"
#include "BookOfAlchemyManager.h"
#include "AlchemyManager.h"
#include "TimerManager.h"
#include "ProjectEleri/UI/CalendarScreen.h"
#include "ProjectEleri/UI/InteractionWidget.h"
#include "UI/AlchemyWidget.h"
#include "UI/EleriBaseWidget.h"
#include "ProjectEleri/GameObjects/BookActor.h"
#include "UI/TradeWidget.h"
#include "ProjectEleri/Public/UI/SelectionManager.h"
#include "ProjectEleri/DialogueSystem/DialogueWidget.h"
AEleriPlayerController::AEleriPlayerController(const FObjectInitializer &ObjectInitializer)
: Super(ObjectInitializer)
{
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.bTickEvenWhenPaused = true;
}
void AEleriPlayerController::BeginPlay()
{
Super::BeginPlay();
PlayerCharacter = Cast<AMyCharacter>(GetCharacter());
MoveActorsComp = PlayerCharacter->GetComponentByClass<UMoveActorsComponent>();
MainGameUI = CreateWidget<UMainGameWidget>(this, MainGameWidgetBlueprint);
MainGameUI->AddToViewport();
if (UCharacterMovementComponent *CharMovement = PlayerCharacter->GetCharacterMovement())
{
CharMovement->MaxWalkSpeed = MinMovementSpeed;
}
MovementComponent = PlayerCharacter->GetComponentByClass<UCharacterMovementComponent>();
MovementDirection = FVector2D(0, -1);
bFlying = false;
BookOfAlchemyManager = Cast<ABookOfAlchemyManager>(UGameplayStatics::GetActorOfClass(GetWorld(), ABookOfAlchemyManager::StaticClass()));
AlchemyManager = Cast<AAlchemyManager>(UGameplayStatics::GetActorOfClass(GetWorld(), AAlchemyManager::StaticClass()));
SelectionManagerInventorySlots = NewObject<USelectionManager>();
}
void AEleriPlayerController::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (ACharacter *Char = GetCharacter())
{
if (UCharacterMovementComponent *CharMovement = Char->GetCharacterMovement())
{
if (CharMovement->IsFalling())
{
CharMovement->GravityScale = 25;
}
else
{
CharMovement->GravityScale = 3;
}
}
}
if (!ActorsOverlappingWith.IsEmpty())
{
for (int32 i = 0; i < ActorsOverlappingWith.Num(); i++)
{
if (!ActorsOverlappingWith[i]->Implements<UZoneInteractableInterface>() || !IZoneInteractableInterface::Execute_IsInteractable(ActorsOverlappingWith[i]))
{
RemoveInteractableObject(ActorsOverlappingWith[i]);
i--;
}
}
if (!IsInMenu() && !bIsInteractionMenuVisible)
{
ToggleInteractionMenu(true);
}
else if (IsInMenu() && bIsInteractionMenuVisible)
{
ToggleInteractionMenu(false);
}
}
if (TickBookAnimating)
{
TickBookTimer -= DeltaTime;
if (TickBookTimer <= 0.f)
{
DisableBookAnimating();
}
}
}
// BIND INPUT
void AEleriPlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
// Make sure that we are using a UEnhancedInputComponent; if not, the project is not configured correctly.
if (UEnhancedInputComponent *PlayerEnhancedInputComponent = Cast<UEnhancedInputComponent>(InputComponent))
{
if (MoveAction)
{
PlayerEnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AEleriPlayerController::OnMove);
}
if (StartFlyingAction)
{
PlayerEnhancedInputComponent->BindAction(StartFlyingAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnStartFlyingAction);
}
if (SprintAction)
{
PlayerEnhancedInputComponent->BindAction(SprintAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnSprint);
PlayerEnhancedInputComponent->BindAction(SprintAction, ETriggerEvent::Completed, this, &AEleriPlayerController::OnStopSprint);
PlayerEnhancedInputComponent->BindAction(SprintAction, ETriggerEvent::Triggered, this, &AEleriPlayerController::OnFlyDownwardsAction);
}
if (JumpAction)
{
PlayerEnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnJump);
PlayerEnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &AEleriPlayerController::OnStopJump);
PlayerEnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Triggered, this, &AEleriPlayerController::OnFlyUpwardsAction);
}
if (LookAction)
{
PlayerEnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AEleriPlayerController::OnLook);
}
if (ToggleCameraLook)
{
PlayerEnhancedInputComponent->BindAction(ToggleCameraLook, ETriggerEvent::Started, this, &AEleriPlayerController::OnLookEnable);
PlayerEnhancedInputComponent->BindAction(ToggleCameraLook, ETriggerEvent::Completed, this, &AEleriPlayerController::OnLookDisable);
}
if (WateringAction)
{
PlayerEnhancedInputComponent->BindAction(WateringAction, ETriggerEvent::Started, this,
&AEleriPlayerController::OnWateringActionStart);
PlayerEnhancedInputComponent->BindAction(WateringAction, ETriggerEvent::Completed, this,
&AEleriPlayerController::OnWateringActionEnd);
}
if (WateringThrowAction)
{
PlayerEnhancedInputComponent->BindAction(WateringThrowAction, ETriggerEvent::Started, this,
&AEleriPlayerController::OnWateringThrowAction);
}
if (OpenMainMenuAction)
{
PlayerEnhancedInputComponent->BindAction(OpenMainMenuAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnMainMenuToggle);
}
if (InventoryAction)
{
PlayerEnhancedInputComponent->BindAction(InventoryAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnInventoryToggle);
}
if (BookAction)
{
PlayerEnhancedInputComponent->BindAction(BookAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnBookToggle);
}
if (OrdersAction)
{
PlayerEnhancedInputComponent->BindAction(OrdersAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnOrdersToggle);
}
if (CalendarAction)
{
PlayerEnhancedInputComponent->BindAction(CalendarAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnCalendarToggle);
}
if (InteractAction)
{
PlayerEnhancedInputComponent->BindAction(InteractAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnInteract);
}
if (InteractExitAction)
{
PlayerEnhancedInputComponent->BindAction(InteractExitAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnInteractExit);
}
if (WaterSeedAction)
{
PlayerEnhancedInputComponent->BindAction(WaterSeedAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnHarvestSeed);
}
if (UiBackAction)
{
PlayerEnhancedInputComponent->BindAction(UiBackAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnControllerBackAction);
}
if (UiTabLeftAction)
{
PlayerEnhancedInputComponent->BindAction(UiTabLeftAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnControllerTabLeftAction);
}
if (UiTabRightAction)
{
PlayerEnhancedInputComponent->BindAction(UiTabRightAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnControllerTabRightAction);
}
//---------------------
// OBJECT REMOVAL INPUTS
//---------------------
if (StartObjectRemovalModeAction)
{
PlayerEnhancedInputComponent->BindAction(StartObjectRemovalModeAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnStartObjectRemovalAction);
}
if (RemoveAction)
{
PlayerEnhancedInputComponent->BindAction(RemoveAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnRemoveAction);
}
if (ExitRemoveModeAction)
{
PlayerEnhancedInputComponent->BindAction(ExitRemoveModeAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnExitRemoveModeAction);
}
if (StartMovingAction)
{
PlayerEnhancedInputComponent->BindAction(StartMovingAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnStartMovingAction);
}
if (PlaceObjectAction)
{
PlayerEnhancedInputComponent->BindAction(PlaceObjectAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnPlaceObjectAction);
}
if (RotateObjectAction)
{
PlayerEnhancedInputComponent->BindAction(RotateObjectAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnRotateObjectAction);
}
if (ToggleGridAction)
{
PlayerEnhancedInputComponent->BindAction(ToggleGridAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnToggleGridAction);
}
//---------------------
// BOOK INPUTS
//---------------------
if (BookNextPageAction)
{
PlayerEnhancedInputComponent->BindAction(BookNextPageAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnBookNextPage);
}
if (BookPreviousPageAction)
{
PlayerEnhancedInputComponent->BindAction(BookPreviousPageAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnBookPreviousPage);
}
if (BookItemTabAction)
{
PlayerEnhancedInputComponent->BindAction(BookItemTabAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnBookItemTab);
}
if (BookPotionTabAction)
{
PlayerEnhancedInputComponent->BindAction(BookPotionTabAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnBookPotionTab);
}
if (BookNextLetterAction)
{
PlayerEnhancedInputComponent->BindAction(BookNextLetterAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnBookNextLetter);
}
if (BookPreviousLetterAction)
{
PlayerEnhancedInputComponent->BindAction(BookPreviousLetterAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnBookPreviousLetter);
}
if (BookExitAction)
{
PlayerEnhancedInputComponent->BindAction(BookExitAction, ETriggerEvent::Started, this, &AEleriPlayerController::OnBookExit);
}
//---------------------
// ALCHEMY INPUTS
//---------------------
if (AlchemyStirringDirectionalInput)
{
PlayerEnhancedInputComponent->BindAction(AlchemyStirringDirectionalInput, ETriggerEvent::Triggered, this,
&AEleriPlayerController::OnAlchemyStirringDirectionInput);
}
if (AlchemyConfirmInput)
{
PlayerEnhancedInputComponent->BindAction(AlchemyConfirmInput, ETriggerEvent::Started, this,
&AEleriPlayerController::OnAlchemyConfirmInput);
}
//---------------------
// INTERACTION MENU INPUTS
//---------------------
if (InteractionMenuSelectAction)
{
PlayerEnhancedInputComponent->BindAction(InteractionMenuSelectAction, ETriggerEvent::Started, this,
&AEleriPlayerController::OnInteractionMenuSelectAction);
}
if (InteractionMenuUpAction)
{
PlayerEnhancedInputComponent->BindAction(InteractionMenuUpAction, ETriggerEvent::Started, this,
&AEleriPlayerController::OnInteractionMenuUpAction);
}
if (InteractionMenuDownAction)
{
PlayerEnhancedInputComponent->BindAction(InteractionMenuDownAction, ETriggerEvent::Started, this,
&AEleriPlayerController::OnInteractionMenuDownAction);
}
}
}
// INIT
void AEleriPlayerController::ClientRestart_Implementation(APawn *NewPawn)
{
Super::ClientRestart_Implementation(NewPawn);
// Get the Enhanced Input Local Player Subsystem from the Local Player related to our Player Controller.
if (UEnhancedInputLocalPlayerSubsystem *Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
{
// PawnClientRestart can run more than once in an Actor's lifetime, so start by clearing out any leftover mappings.
Subsystem->ClearAllMappings();
// Add each mapping context, along with their priority values. Higher values outprioritize lower values.
Subsystem->AddMappingContext(MovementContext, 1);
// Subsystem->AddMappingContext(MainUiContext, 2);
Subsystem->AddMappingContext(UiContext, 3);
Subsystem->AddMappingContext(ActionContext, 4);
}
}
// LOCOMOTION INPUT
void AEleriPlayerController::OnMove(const FInputActionValue &Value)
{
if (IsInMenu())
return;
FVector2D AnalogueValue = Value.Get<FInputActionValue::Axis2D>();
MovementDirection = AnalogueValue;
if (PlayerCharacter)
{
FRotator CtrlRotation = GetControlRotation();
FRotator YawRotation(0, CtrlRotation.Yaw, 0);
// FVector ForwardFacing = UKismetMathLibrary::GetForwardVector(bFlying? PlayerCameraManager->GetCameraRotation() : CharRotForward);
float AppliedMovementVelocity = 1.f; // MovementVelocity * (bFlying? 0.5f : 1.f);
FVector ForwardVec = PlayerCharacter->GetPlayerCamera()->GetForwardVector();
FVector RightVec = PlayerCharacter->GetPlayerCamera()->GetRightVector();
PlayerCharacter->AddMovementInput(ForwardVec, MovementDirection.Y * AppliedMovementVelocity);
PlayerCharacter->AddMovementInput(RightVec, MovementDirection.X * AppliedMovementVelocity);
}
}
void AEleriPlayerController::OnSprint(const FInputActionValue &Value)
{
if (IsInMenu() || Watering)
return;
ACharacter *Char = GetCharacter();
if (Char != nullptr && !bFlying)
{
MovementVelocity = 13.0f;
if (UCharacterMovementComponent *CharMovement = Char->GetCharacterMovement())
{
CharMovement->MaxWalkSpeed = MaxMovementSpeed;
}
}
}
void AEleriPlayerController::OnStopSprint(const FInputActionValue &Value)
{
ACharacter *Char = GetCharacter();
if (Char != nullptr)
{
MovementVelocity = 1.0f;
if (UCharacterMovementComponent *CharMovement = Char->GetCharacterMovement())
{
CharMovement->MaxWalkSpeed = MinMovementSpeed;
}
}
}
void AEleriPlayerController::OnJump(const FInputActionValue &Value)
{
if (IsInMenu() || Watering)
return;
ACharacter *Char = GetCharacter();
if (Char != nullptr && !bFlying)
{
Char->Jump();
}
}
void AEleriPlayerController::OnStopJump(const FInputActionValue &Value)
{
ACharacter *Char = GetCharacter();
if (Char != nullptr)
{
Char->StopJumping();
}
}
void AEleriPlayerController::OnLook(const FInputActionValue &Value)
{
if (IsInMenu())
return;
FVector2D AnalogueValue = Value.Get<FInputActionValue::Axis2D>();
if (PlayerCharacter != nullptr)
{
AddYawInput(AnalogueValue.X);
AddPitchInput(AnalogueValue.Y);
}
}
void AEleriPlayerController::OnLookEnable(const FInputActionValue &Value)
{
if (IsInMenu())
return;
AMyCharacter *Char = Cast<AMyCharacter>(GetCharacter());
if (Char != nullptr)
{
Char->RotateCam = true;
}
}
void AEleriPlayerController::OnLookDisable(const FInputActionValue &Value)
{
if (IsInMenu())
return;
AMyCharacter *Char = Cast<AMyCharacter>(GetCharacter());
if (Char != nullptr)
{
Char->RotateCam = false;
}
}
void AEleriPlayerController::OnWateringActionStart(const FInputActionValue &Value)
{
if (!PlayerCharacter ||
PlayerCharacter->CurrentlyDoing != ECurrentlyDoing::NOTHING ||
MainGameUI->IsAlchemyOpen() ||
IsInMenu())
return;
Watering = true;
PlayerCharacter->BeginWatering();
OnWatering.Broadcast(Watering);
OnChangeInputContext.Broadcast(2);
}
void AEleriPlayerController::OnWateringActionEnd(const FInputActionValue &Value)
{
if (!PlayerCharacter ||
PlayerCharacter->CurrentlyDoing != ECurrentlyDoing::NOTHING ||
!Watering)
return;
Watering = false;
PlayerCharacter->EndWatering();
OnWatering.Broadcast(Watering);
OnChangeInputContext.Broadcast(1);
}
void AEleriPlayerController::OnWateringThrowAction(const FInputActionValue &Value)
{
if (!PlayerCharacter ||
!Watering ||
PlayerCharacter->CurrentlyDoing != ECurrentlyDoing::NOTHING)
return;
PlayerCharacter->ThrowWaterBall();
OnChangeInputContext.Broadcast(1);
}
void AEleriPlayerController::OnStartFlyingAction(const FInputActionValue &Value)
{
if (bAnimatingFlying)
return;
bAnimatingFlying = true;
bFlying = !bFlying;
if (bFlying)
{
MovementComponent->AddImpulse(FVector::UpVector * 400000.f, false);
FTimerHandle FlyTimerHandle;
GetWorld()->GetTimerManager().SetTimer(FlyTimerHandle, FTimerDelegate::CreateLambda([this]
{
if (bFlying)
{
MovementComponent->Velocity = FVector::ZeroVector;
MovementComponent->SetMovementMode(EMovementMode::MOVE_Flying);
} }),
0.25f, false);
}
else
{
MovementComponent->SetMovementMode(EMovementMode::MOVE_Walking);
}
if (UEnhancedInputLocalPlayerSubsystem *Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
{
// PawnClientRestart can run more than once in an Actor's lifetime, so start by clearing out any leftover mappings.
if (bFlying)
{
Subsystem->RemoveMappingContext(MovementContext);
Subsystem->AddMappingContext(FlyingContext, 1);
}
else
{
Subsystem->RemoveMappingContext(FlyingContext);
Subsystem->AddMappingContext(MovementContext, 1);
}
}
if (PlayerCharacter)
{
PlayerCharacter->ToggleBroomActor(bFlying);
PlayerCharacter->SetNewCameraPitches(bFlying ? -30 : PlayerCharacter->CameraPitchMin, bFlying ? 30 : PlayerCharacter->CameraPitchMax);
PlayerCharacter->OnToggleFlying(bFlying);
}
OnPlayerToggleFlying.Broadcast(bFlying);
}
void AEleriPlayerController::OnFlyUpwardsAction(const FInputActionValue &Value)
{
ACharacter *Char = GetCharacter();
if (bFlying)
{
float AnalogueValue = Value.Get<FInputActionValue::Axis1D>();
Char->AddMovementInput(Char->GetActorUpVector(), AnalogueValue);
}
}
void AEleriPlayerController::OnFlyDownwardsAction(const FInputActionValue &Value)
{
ACharacter *Char = GetCharacter();
if (bFlying)
{
float AnalogueValue = Value.Get<FInputActionValue::Axis1D>();
Char->AddMovementInput(Char->GetActorUpVector(), -AnalogueValue);
}
}
void AEleriPlayerController::OnStartObjectRemovalAction(const FInputActionValue &Value)
{
if (MoveActorsComp->MovingActor)
{
ExitRemoveMode();
return;
}
if (IsInMenu() || Paused)
return;
MoveActorsComp->StartObjectRemoval(!MoveActorsComp->IsRemovingMode());
PlacingStuff = !MoveActorsComp->IsRemovingMode();
// Get the Enhanced Input Local Player Subsystem from the Local Player related to our Player Controller.
if (UEnhancedInputLocalPlayerSubsystem *Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
{
Subsystem->AddMappingContext(RemoveModeContext, 8);
}
OnRemovalModeToggle.Broadcast(true);
}
void AEleriPlayerController::OnRemoveAction(const FInputActionValue &Value)
{
if (MoveActorsComp->MovingActor)
{
MoveActorsComp->PlaceableActionUsed(ERemovalAction::REMOVE);
MoveActorsComp->MovingActor = nullptr;
MoveActorsComp->RemovalModePlacingStack = 0;
}
}
void AEleriPlayerController::ExitRemoveMode()
{
if (MoveActorsComp->MovingActor)
{
MoveActorsComp->PlaceableActionUsed(ERemovalAction::EXIT);
MoveActorsComp->StartObjectRemoval(false);
if (IsValid(MoveActorsComp->MovingActor))
{
MoveActorsComp->MovingActor->Place(true);
}
MoveActorsComp->RemoveObjectForPlacing();
}
else
{
MoveActorsComp->StartObjectRemoval(false);
}
PlayerCharacter->bAlreadyInteracting = false;
PlayerCharacter->CurrentlyDoing = ECurrentlyDoing::NOTHING;
PlacingStuff = false;
OnRemovalModeToggle.Broadcast(false);
}
void AEleriPlayerController::OnExitRemoveModeAction(const FInputActionValue &Value)
{
ExitRemoveMode();
}
void AEleriPlayerController::OnStartMovingAction(const FInputActionValue &Value)
{
if (MoveActorsComp->MovingActor)
{
MoveActorsComp->PlaceableActionUsed(ERemovalAction::START_MOVE);
MoveActorsComp->StartObjectRemoval(false);
}
}
void AEleriPlayerController::OnPlaceObjectAction(const FInputActionValue &Value)
{
if (MoveActorsComp->MovingActor && !MoveActorsComp->MovingActor->CanPlace())
return;
if (MoveActorsComp->MovingActor)
{
UClass *ClassToLoad = MoveActorsComp->MovingActor->GetClass();
FVector Location = MoveActorsComp->MovingActor->GetActorLocation();
UInventoryComponent *Inventory = MoveActorsComp->MovingActor->InventoryRef;
FItemStack Stack = MoveActorsComp->MovingActor->ItemStack;
if (!MoveActorsComp->PlaceableActionUsed(ERemovalAction::PLACE))
return;
if (Inventory)
{
Stack.Stack = Inventory->GetStackForItem(Stack.ItemId, Stack.Seed, Stack.HQ);
}
else
{
Stack.Stack = 0;
}
if (ClassToLoad && Stack.Stack > 0)
{
FTransform PlaceableTransform;
PlaceableTransform.SetLocation(Location);
if (ARemovableStaticMeshActor *SpawnedActor = UMainBlueprintFunctionLibrary::SpawnPlaceable(GetWorld(), ClassToLoad, PlaceableTransform, FVector::OneVector))
{
if (!MoveActorsComp || !MoveActorsComp->IsRemovingMode())
{
SpawnedActor->Destroy();
MoveActorsComp->MovingActor = nullptr;
return;
}
SpawnedActor->BindToItem(Inventory, Stack);
SpawnedActor->PickUp();
MoveActorsComp->MovingActor = SpawnedActor;
}
}
if (MoveActorsComp->RemovalModePlacingStack <= 0)
{
MoveActorsComp->StartObjectRemoval(false);
}
}
else
{
OnInteract(Value);
}
}
void AEleriPlayerController::OnRotateObjectAction(const FInputActionValue &Value)
{
float RotateForward = Value.Get<FInputActionValue::Axis1D>();
if (MoveActorsComp->MovingActor)
MoveActorsComp->MovingActor->Rotate(RotateForward > 0);
}
void AEleriPlayerController::OnToggleGridAction(const FInputActionValue &Value)
{
if (MoveActorsComp)
{
MoveActorsComp->ToggleGridMovement();
}
}
void AEleriPlayerController::AddInteractableObject(UObject *ObjectToAdd)
{
if (IsValid(ObjectToAdd) && ObjectToAdd->Implements<UZoneInteractableInterface>() && IZoneInteractableInterface::Execute_IsInteractable(ObjectToAdd))
{
FText InteractableText = IZoneInteractableInterface::Execute_GetInteractionText(ObjectToAdd);
if (UMainGameWidget *MainWidget = UMainBlueprintFunctionLibrary::GetMainGameWidget(this))
{
if (UInteractionWidget *InteractionWidget = MainWidget->GetInteractionWidget())
{
InteractionWidget->PushInteractableObject(ObjectToAdd, InteractableText);
}
IZoneInteractableInterface::Execute_PlayerEntered(ObjectToAdd, true);
}
ActorsOverlappingWith.Add(ObjectToAdd);
}
if (!ActorsOverlappingWith.IsEmpty())
{
ToggleInteractionMenu(true);
}
if (ActorsOverlappingWith.Num() == 1)
{
SelectedInteractable = ActorsOverlappingWith[0];
}
}
void AEleriPlayerController::RemoveInteractableObject(UObject *ObjectToAdd)
{
if (IsPaused())
return;
if (IsValid(ObjectToAdd) && ObjectToAdd->Implements<UZoneInteractableInterface>())
{
FText InteractableText = IZoneInteractableInterface::Execute_GetInteractionText(ObjectToAdd);
if (UMainGameWidget *MainWidget = UMainBlueprintFunctionLibrary::GetMainGameWidget(this))
{
if (UInteractionWidget *InteractionWidget = MainWidget->GetInteractionWidget())
{
InteractionWidget->PopInteractableObject(ObjectToAdd);
}
}
IZoneInteractableInterface::Execute_PlayerEntered(ObjectToAdd, false);
}
ActorsOverlappingWith.Remove(ObjectToAdd);
if (SelectedInteractable == ObjectToAdd)
{
SelectedInteractable = nullptr;
if (!ActorsOverlappingWith.IsEmpty())
{
SelectedInteractable = ActorsOverlappingWith[ActorsOverlappingWith.Num() - 1];
}
}
if (ActorsOverlappingWith.IsEmpty())
{
ToggleInteractionMenu(true);
}
}
void AEleriPlayerController::ToggleInteractionMenu(bool bActive)
{
bIsInteractionMenuVisible = bActive;
if (UMainGameWidget *MainWidget = UMainBlueprintFunctionLibrary::GetMainGameWidget(this))
{
if (UInteractionWidget *InteractionWidget = MainWidget->GetInteractionWidget())
{
InteractionWidget->OnDisplayInteractionMenu.Broadcast(bActive);
}
if (UEnhancedInputLocalPlayerSubsystem *Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
{
if (bActive)
Subsystem->AddMappingContext(InteractionMenuContext, 15);
else
Subsystem->RemoveMappingContext(InteractionMenuContext);
}
}
}
void AEleriPlayerController::OnInteractionMenuSelectAction(const FInputActionValue &Value)
{
if (SelectedInteractable)
{
IZoneInteractableInterface::Execute_Interact(SelectedInteractable);
if (!IZoneInteractableInterface::Execute_KeepInteractionMenuOpenWhenSelected(SelectedInteractable))
{
ToggleInteractionMenu(false);
}
}
}
void AEleriPlayerController::OnInteractionMenuUpAction(const FInputActionValue &Value)
{
if (UMainGameWidget *MainWidget = UMainBlueprintFunctionLibrary::GetMainGameWidget(this))
{
if (UInteractionWidget *InteractionWidget = MainWidget->GetInteractionWidget())
{
SelectedInteractable = InteractionWidget->SelectInteractableObject(false);
}
}
}
void AEleriPlayerController::OnInteractionMenuDownAction(const FInputActionValue &Value)
{
if (UMainGameWidget *MainWidget = UMainBlueprintFunctionLibrary::GetMainGameWidget(this))
{
if (UInteractionWidget *InteractionWidget = MainWidget->GetInteractionWidget())
{
SelectedInteractable = InteractionWidget->SelectInteractableObject(true);
}
}
}
void AEleriPlayerController::OnControllerUpAction(const FInputActionValue &Value)
{
if (IsInMenu())
{
OnUiButtonPressed.Broadcast(UiInputType::UP);
}
}
void AEleriPlayerController::OnControllerDownAction(const FInputActionValue &Value)
{
if (IsInMenu())
{
OnUiButtonPressed.Broadcast(UiInputType::DOWN);
}
}
void AEleriPlayerController::OnControllerLeftAction(const FInputActionValue &Value)
{
if (IsInMenu())
{
OnUiButtonPressed.Broadcast(UiInputType::LEFT);
}
}
void AEleriPlayerController::OnControllerRightAction(const FInputActionValue &Value)
{
if (IsInMenu())
{
OnUiButtonPressed.Broadcast(UiInputType::RIGHT);
}
}
void AEleriPlayerController::OnControllerConfirmAction(const FInputActionValue &Value)
{
if (MainGameUI->GetWidgetStack().IsEmpty())
{
return;
}
MainGameUI->GetWidgetStack()[MainGameUI->GetWidgetStack().Num() - 1]->HandleUiInputAction(EEleriUIInputAction::Select);
}
void AEleriPlayerController::OnControllerBackAction(const FInputActionValue &Value)
{
OnUiButtonPressed.Broadcast(UiInputType::BACK);
if (MainGameUI->GetWidgetStack().IsEmpty())
{
return;
}
MainGameUI->GetWidgetStack()[MainGameUI->GetWidgetStack().Num() - 1]->HandleUiInputAction(EEleriUIInputAction::Back);
}
void AEleriPlayerController::OnControllerTabLeftAction(const FInputActionValue &Value)
{
if (MainGameUI->GetWidgetStack().IsEmpty())
{
return;
}
MainGameUI->GetWidgetStack()[MainGameUI->GetWidgetStack().Num() - 1]->HandleUiInputAction(EEleriUIInputAction::TabLeft);
}
void AEleriPlayerController::OnControllerTabRightAction(const FInputActionValue &Value)
{
if (MainGameUI->GetWidgetStack().IsEmpty())
{
return;
}
MainGameUI->GetWidgetStack()[MainGameUI->GetWidgetStack().Num() - 1]->HandleUiInputAction(EEleriUIInputAction::TabRight);
}
// UI BIND
void AEleriPlayerController::OnMainMenuToggle(const FInputActionValue &Value)
{
if (!IsValid(MainGameUI))
return;
if (MainGameUI->IsMainMenuOpen())
{
CloseMainMenu();
}
else
{
OpenMainMenu();
}
}
void AEleriPlayerController::OnInventoryToggle(const FInputActionValue &Value)
{
if (Paused || (IsInMenu() && !MainGameUI->IsInventoryOpen()) || !MoveActorsComp || MoveActorsComp->IsRemovingMode())
return;
OpenInventory(false, false, nullptr, TArray<EInventoryTabType>());
}
void AEleriPlayerController::OnBookToggle(const FInputActionValue &Value)
{
if (Paused || IsDialogueOpen() || (IsInMenu() && !MainGameUI->IsBookOpen()) || !MoveActorsComp || MoveActorsComp->IsRemovingMode())
return;
OpenBookOfAlchemy(nullptr);
}
void AEleriPlayerController::OnOrdersToggle(const FInputActionValue &Value)
{
if (Paused || IsDialogueOpen() || IsInMenu() || !MoveActorsComp || MoveActorsComp->IsRemovingMode())
return;
if (OrdersOpen)
{
CloseOrdersUI();
}
else
{
}
}
void AEleriPlayerController::OnCalendarToggle(const FInputActionValue &Value)
{
if (Paused || IsDialogueOpen() || (IsInMenu() && !MainGameUI->IsCalendarOpen()) || !MoveActorsComp || MoveActorsComp->IsRemovingMode())
return;
OpenCalendarWindow();
}
void AEleriPlayerController::OnBookNextPage(const FInputActionValue &Value)
{
if (!IsValid(BookOfAlchemyManager))
return;
BookOfAlchemyManager->FlipPage(true);
}
void AEleriPlayerController::OnBookPreviousPage(const FInputActionValue &Value)
{
if (!IsValid(BookOfAlchemyManager))
return;
BookOfAlchemyManager->FlipPage(false);
}
void AEleriPlayerController::OnBookItemTab(const FInputActionValue &Value)
{
if (!IsValid(BookOfAlchemyManager))
return;
BookOfAlchemyManager->SwitchTab(0);
}
void AEleriPlayerController::OnBookPotionTab(const FInputActionValue &Value)
{
if (!IsValid(BookOfAlchemyManager))
return;
BookOfAlchemyManager->SwitchTab(1);
}
void AEleriPlayerController::OnBookNextLetter(const FInputActionValue &Value)
{
if (!IsValid(BookOfAlchemyManager))
return;
BookOfAlchemyManager->SelectLetter(BookOfAlchemyManager->GetNextPreviousLetter(BookOfAlchemyManager->CurrentlySelectedLetter, true));
}
void AEleriPlayerController::OnBookPreviousLetter(const FInputActionValue &Value)
{
if (!IsValid(BookOfAlchemyManager))
return;
BookOfAlchemyManager->SelectLetter(BookOfAlchemyManager->GetNextPreviousLetter(BookOfAlchemyManager->CurrentlySelectedLetter, false));
}
void AEleriPlayerController::OnBookExit(const FInputActionValue &Value)
{
// CloseBookOfAlchemy();
}
void AEleriPlayerController::OnAlchemyStirringDirectionInput(const FInputActionValue &Value)
{
if (!PlayerCharacter)
return;
AlchemyManager->SetStirringDirection(Value.Get<FInputActionValue::Axis2D>());
}
void AEleriPlayerController::OnAlchemyConfirmInput(const FInputActionValue &Value)
{
if (!PlayerCharacter)
return;
AlchemyManager->MinigameConfirmInput();
}
UUserWidget *AEleriPlayerController::OpenInventory(bool JustSelecting, bool Shop, UInventoryComponent *Inventory, TArray<EInventoryTabType> RestrictTabs, bool bSelectMultiple, bool bShowDescription, bool bShowPropertyMap)
{
UInventoryComponent *PlayerInventory = Cast<UInventoryComponent>(PlayerCharacter->GetComponentByClass(UInventoryComponent::StaticClass()));
if (!IsValid(PlayerInventory))
return nullptr;
// If we pass nothing into this function we're opening the player inventory
// If we pass something we're opening a shop/trade and the other inventory is the npc inventory
UInventoryComponent *MainInv = PlayerInventory;
UInventoryComponent *OtherInv = IsValid(Inventory) ? Inventory : nullptr;
MainGameUI->OpenWidget(MainGameUI->GetInventoryWidget());
//MainGameUI->GetInventoryWidget()->ToggleWidget(true);
MainGameUI->GetInventoryWidget()->Setup(MainInv, OtherInv, Shop, JustSelecting, RestrictTabs, bSelectMultiple, bShowDescription, bShowPropertyMap);
return MainGameUI->GetInventoryWidget();
}
void AEleriPlayerController::CloseInventory()
{
MainGameUI->CloseWidget(MainGameUI->GetInventoryWidget());
}
UUserWidget *AEleriPlayerController::OpenBookOfAlchemy(UItemDataAsset *ItemToPresent)
{
if (!IsValid(PlayerCharacter->GetBook()) || bBookAnimating)
return nullptr;
bBookAnimating = true;
MainGameUI->GetBookWidget()->Setup(ItemToPresent, false);
PlayerCharacter->ToggleBook(true);
MainGameUI->OpenWidget(MainGameUI->GetBookWidget());
MainGameUI->ToggleGameMenu(false);
// Get the Enhanced Input Local Player Subsystem from the Local Player related to our Player Controller.
if (UEnhancedInputLocalPlayerSubsystem *Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
{
// If for whatever reason...
Subsystem->RemoveMappingContext(BookModeContext);
// Add each mapping context, along with their priority values. Higher values outprioritize lower values.
Subsystem->AddMappingContext(BookModeContext, 98);
}
TickBookAnimating = true;
return MainGameUI->GetBookWidget();
}
void AEleriPlayerController::CloseBookOfAlchemy()
{
if (bBookAnimating)
return;
bBookAnimating = true;
// for the animation of closing
FTimerHandle TimerHandle;
GetWorld()->GetTimerManager().SetTimer(TimerHandle, FTimerDelegate::CreateLambda([this]()
{
MainGameUI->ToggleGameMenu(true);
}), 0.5f, false);
// Get the Enhanced Input Local Player Subsystem from the Local Player related to our Player Controller.
if (UEnhancedInputLocalPlayerSubsystem *Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
{
Subsystem->RemoveMappingContext(BookModeContext);
}
TickBookAnimating = true;
}
void AEleriPlayerController::DisableBookAnimating()
{
bBookAnimating = false;
TickBookAnimating = false;
TickBookTimer = 0.6f;
}
void AEleriPlayerController::CloseOrdersUI()
{
OrdersOpen = false;
OrdersUI->RemoveFromParent();
if (MenuStack.Num() == 0)
{
SetShowMouseCursor(false);
SetInputMode(FInputModeGameOnly());
}
}
UMainMenuWidget *AEleriPlayerController::OpenMainMenu()
{
if (!IsValid(MainGameUI))
return nullptr;
MainGameUI->OpenWidget(MainGameUI->GetMainMenuWidget());
return MainGameUI->GetMainMenuWidget();
}
void AEleriPlayerController::CloseMainMenu()
{
MainGameUI->CloseWidget(MainGameUI->GetMainMenuWidget());
}
UEleriBaseWidget *AEleriPlayerController::ToggleAlchemyMenu(bool bOpen)
{
if (MainGameUI->AnyWidgetOpen())
return nullptr;
MainGameUI->OpenWidget(MainGameUI->GetAlchemyWidget());
return MainGameUI->GetAlchemyWidget();
}
UEleriBaseWidget *AEleriPlayerController::ToggleDialogueWindow(bool bOpen)
{
if (!IsValid(MainGameUI->GetDialogueWidget()) || MainGameUI->GetDialogueWidget()->IsAnimating())
return nullptr;
MainGameUI->OpenWidget(MainGameUI->GetDialogueWidget());
return MainGameUI->GetDialogueWidget();
}
UEleriBaseWidget *AEleriPlayerController::ToggleNotificationWindow(bool bOpen)
{
if (!IsValid(MainGameUI->GetBigNotificationWidget()))
return nullptr;
if (MainGameUI->IsBigNotificationOpen())
{
MainGameUI->CloseWidget(MainGameUI->GetBigNotificationWidget());
}
else
{
MainGameUI->OpenWidget(MainGameUI->GetBigNotificationWidget());
}
return MainGameUI->GetBigNotificationWidget();
}
UTradeWidget *AEleriPlayerController::OpenTradeWindow(UInventoryComponent *Inventory, const TArray<EInventoryTabType>& InRestrictTabs)
{
if (!IsValid(PlayerCharacter))
return nullptr;
if (UMainGameWidget *MainWidget = GetMainGameWidget())
{
MainWidget->OpenTradeWidget(Inventory, InRestrictTabs);
return MainGameUI->GetTradeWidget();
}
return nullptr;
}
UCalendarScreen* AEleriPlayerController::OpenCalendarWindow()
{
MainGameUI->OpenWidget(MainGameUI->GetCalendarWidget());
return MainGameUI->GetCalendarWidget();
}
UEleriBaseWidget* AEleriPlayerController::OpenBazarWindow() {
MainGameUI->OpenWidget(MainGameUI->GetBazarWidget());
return MainGameUI->GetBazarWidget();
}
void AEleriPlayerController::ToggleBazarInput(bool bActive)
{
}
void AEleriPlayerController::OnInteract(const FInputActionValue &Value)
{
if (!IsValid(PlayerCharacter))
return;
if (PlayerCharacter->GetIsPlanting())
PlayerCharacter->PlantSeed();
PlayerCharacter->OnInteract.Broadcast();
}
void AEleriPlayerController::OnInteractExit(const FInputActionValue &Value)
{
if (!IsValid(PlayerCharacter))
return;
// if (PlayerCharacter->GetIsPlanting()) PlayerCharacter->PlantSeed();
PlayerCharacter->OnInteractExit.Broadcast();
OnChangeInputContext.Broadcast(1);
}
void AEleriPlayerController::OnHarvestSeed(const FInputActionValue &Value)
{
}
void AEleriPlayerController::StartMinigame(EMinigameType MinigameType, const TSoftObjectPtr<UBaseMinigameDataAsset> &DataAsset)
{
if (!IsValid(PlayerCharacter) ||
!IsValid(MainGameUI) ||
MainGameUI->IsAnyMinigameOpen() ||
MinigameType == EMinigameType::NONE)
return;
MainGameUI->ToggleMinigamesWidget(MinigameType, DataAsset);
}
void AEleriPlayerController::CloseMinigame(int32 Score)
{
if (!IsValid(PlayerCharacter) || !IsValid(MainGameUI) || !MainGameUI->IsAnyMinigameOpen())
return;
MainGameUI->ToggleMinigamesWidget(EMinigameType::NONE, nullptr);
if (OnMinigameComplete.IsBound())
{
OnMinigameComplete.Execute(Score);
}
}