AzureAbyss/Source/the_twilight_abyss/Quest/QuestSystem.cpp

162 lines
5.3 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "QuestSystem.h"
#include "Misc/OutputDeviceNull.h"
// Sets default values for this component's properties
UQuestSystem::UQuestSystem()
{
// 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;
static ConstructorHelpers::FClassFinder<UUserWidget> QuestWidgetClass(TEXT("/Game/Blueprints/Quest_UI/Quest_UI"));
QuestWidget = QuestWidgetClass.Class;
static ConstructorHelpers::FClassFinder<UUserWidget> QuestCompletionWidgetClass(TEXT("/Game/Blueprints/Quest_UI/QuestCompletion_UI"));
QuestCompletionWidget = QuestCompletionWidgetClass.Class;
}
// Called when the game starts
void UQuestSystem::BeginPlay()
{
Super::BeginPlay();
PlayerInventory = GetOwner()->FindComponentByClass<UInventoryComponent>();
PlayerInventory->OnInventoryUpdated.AddDynamic(this, &UQuestSystem::CheckActiveQuestConditions);
QuestWidgetInstance = CreateWidget<UUserWidget>(GetWorld(), QuestWidget);
QuestWidgetInstance->AddToViewport();
QuestCompletionWidgetInstance = CreateWidget<UUserWidget>(GetWorld(), QuestCompletionWidget);
QuestCompletionWidgetInstance->AddToViewport();
MainQuestBorder = Cast<UBorder>(QuestWidgetInstance->GetWidgetFromName("MainQuest"));
SubQuestBorder = Cast<UBorder>(QuestWidgetInstance->GetWidgetFromName("SubQuest"));
MainQuestTitle = Cast<UTextBlock>(QuestWidgetInstance->GetWidgetFromName("MainQuest_Text"));
SubQuestTitle = Cast<UTextBlock>(QuestWidgetInstance->GetWidgetFromName("SubQuest_Text"));
MainQuestGoals = Cast<URichTextBlock>(QuestWidgetInstance->GetWidgetFromName("MainGoals_Text"));
SubQuestGoals = Cast<URichTextBlock>(QuestWidgetInstance->GetWidgetFromName("SubGoals_Text"));
QuestCompletionTitle = Cast<UTextBlock>(QuestCompletionWidgetInstance->GetWidgetFromName("QuestTitle_Text"));
if (!ActiveQuests.IsEmpty())
{
MainQuestTitle->SetText(ActiveQuests[0]->Title);
UpdateQuestGoalsUI(ActiveQuests[0]);
}
}
// Called every frame
void UQuestSystem::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}
void UQuestSystem::CheckActiveQuestConditions()
{
for (UQuest* Quest : ActiveQuests)
{
if (Quest->CheckConditions(GetWorldState()))
{
CompletedQuests.Add(Quest);
Quest->ApplyRewards(PlayerInventory);
QuestCompletionTitle->SetText(Quest->Title);
if (Quest->QuestLine == EQuestLine::Sub)
{
bHasSubQuest = false;
SubQuestBorder->SetVisibility(ESlateVisibility::Hidden);
}
if (Quest->bShowQuestCompletedNotification)
{
FOutputDeviceNull AR;
const FString Command = FString::Printf(TEXT("PlayCompletedQuestAnimation"));
QuestCompletionWidgetInstance->CallFunctionByNameWithArguments(*Command, AR, nullptr, true);
}
}
UpdateQuestGoalsUI(Quest);
}
}
UWorldState* UQuestSystem::GetWorldState() const
{
UWorldState* WorldState = NewObject<UWorldState>();
WorldState->Items = PlayerInventory->Items;
WorldState->QuestFlags = QuestFlags;
return WorldState;
}
bool UQuestSystem::AddQuest(UQuest* Quest)
{
if (HasActiveQuest(Quest)) return false;
if (!Quest->CheckPreConditions(GetWorldState())) return false;
ActiveQuests.Add(Quest);
if (Quest->QuestLine == EQuestLine::Sub)
{
bHasSubQuest = true;
SubQuestBorder->SetVisibility(ESlateVisibility::Visible);
SubQuestTitle->SetText(Quest->Title);
UpdateQuestGoalsUI(Quest);
}
else if (Quest->QuestLine == EQuestLine::Main)
{
MainQuestTitle->SetText(Quest->Title);
UpdateQuestGoalsUI(Quest);
}
return true;
}
void UQuestSystem::AddQuestFlag(const FString FlagName, const bool FlagValue)
{
QuestFlags.Add(FlagName, FlagValue);
CheckActiveQuestConditions();
}
bool UQuestSystem::CheckPreConditions(UQuest* Quest) const
{
if (Quest->CheckPreConditions(GetWorldState())) return true;
return false;
}
bool UQuestSystem::HasActiveQuest(UQuest* Quest) const
{
if (ActiveQuests.Contains(Quest)) return true;
return false;
}
void UQuestSystem::UpdateQuestGoalsUI(const UQuest* Quest) const
{
FString GoalsText;
if (!Quest->Goals->QuestFlags.IsEmpty())
{
for (TTuple<FString, bool> QuestFlag : Quest->Goals->QuestFlags)
{
if (Quest->FlagTrueMatch(GetWorldState(), QuestFlag.Key))
{
GoalsText += FString::Printf(TEXT("- <Strike>%s</>\n"), *QuestFlag.Key);
}
else
{
GoalsText += FString::Printf(TEXT("- %s\n"), *QuestFlag.Key);
}
}
}
if (!Quest->Goals->Items.IsEmpty())
{
for (UBaseItem* Item : Quest->Goals->Items)
{
FString Left, Right;
Quest->GetItemCountAndGoalAmount(GetWorldState(), Item).Split("/", &Left, &Right);
if (FCString::Atoi(*Left) >= FCString::Atoi(*Right))
{
GoalsText += FString::Printf(TEXT("- <Strike>%s %s</>\n"), *Quest->GetItemCountAndGoalAmount(GetWorldState(), Item), *Item->ItemDisplayName.ToString());
}
else
{
GoalsText += FString::Printf(TEXT("- %s %s\n"), *Quest->GetItemCountAndGoalAmount(GetWorldState(), Item), *Item->ItemDisplayName.ToString());
}
}
}
if (Quest->QuestLine == EQuestLine::Main) MainQuestGoals->SetText(FText::FromString(GoalsText));
else if (Quest->QuestLine == EQuestLine::Sub) SubQuestGoals->SetText(FText::FromString(GoalsText));
}