Updated Quest System for UI
This commit is contained in:
parent
9bb98b314b
commit
f24fcc2d25
BIN
Content/Blueprints/Combat_UI/CombatCharacter.uasset
(Stored with Git LFS)
BIN
Content/Blueprints/Combat_UI/CombatCharacter.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Blueprints/Quest_UI/QuestCompletion_UI.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Blueprints/Quest_UI/QuestCompletion_UI.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Blueprints/Quest_UI/Quest_UI.uasset
(Stored with Git LFS)
BIN
Content/Blueprints/Quest_UI/Quest_UI.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Blueprints/Quests/Quest_SistersPendant.uasset
(Stored with Git LFS)
BIN
Content/Blueprints/Quests/Quest_SistersPendant.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Blueprints/Quests/Quest_Start.uasset
(Stored with Git LFS)
BIN
Content/Blueprints/Quests/Quest_Start.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Blueprints/Quests/Quest_Start2.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Blueprints/Quests/Quest_Start2.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Dialogue/SM_Merchant_Blueprint.uasset
(Stored with Git LFS)
BIN
Content/Dialogue/SM_Merchant_Blueprint.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Fonts/DT_RichText.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Fonts/DT_RichText.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Levels/Testing/BreakableWall_BP_ExitCave.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Levels/Testing/BreakableWall_BP_ExitCave.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -21,6 +21,7 @@ bool UQuest::CheckPreConditions(UWorldState* WorldState) const
|
|||||||
|
|
||||||
void UQuest::ApplyRewards(UInventoryComponent* Inventory)
|
void UQuest::ApplyRewards(UInventoryComponent* Inventory)
|
||||||
{
|
{
|
||||||
|
if (Rewards.IsEmpty()) return;
|
||||||
for (UBaseItem* Item : Rewards)
|
for (UBaseItem* Item : Rewards)
|
||||||
{
|
{
|
||||||
Inventory->AddItem(Item);
|
Inventory->AddItem(Item);
|
||||||
@ -29,6 +30,7 @@ void UQuest::ApplyRewards(UInventoryComponent* Inventory)
|
|||||||
|
|
||||||
bool UQuest::WorldStateMatch(UWorldState* A, UWorldState* B)
|
bool UQuest::WorldStateMatch(UWorldState* A, UWorldState* B)
|
||||||
{
|
{
|
||||||
|
if (A->Items.IsEmpty() && !B->Items.IsEmpty()) return false;
|
||||||
for (UBaseItem* Item : B->Items)
|
for (UBaseItem* Item : B->Items)
|
||||||
{
|
{
|
||||||
if (!A->Items.Contains(Item) && Item->StackCount > A->Items[A->Items.Find(Item)]->StackCount)
|
if (!A->Items.Contains(Item) && Item->StackCount > A->Items[A->Items.Find(Item)]->StackCount)
|
||||||
@ -36,6 +38,8 @@ bool UQuest::WorldStateMatch(UWorldState* A, UWorldState* B)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (A->QuestFlags.IsEmpty() && !B->QuestFlags.IsEmpty()) return false;
|
||||||
for (TTuple<FString, bool> Flag : B->QuestFlags)
|
for (TTuple<FString, bool> Flag : B->QuestFlags)
|
||||||
{
|
{
|
||||||
if (!A->QuestFlags.Contains(Flag.Key) || A->QuestFlags[Flag.Key] != Flag.Value)
|
if (!A->QuestFlags.Contains(Flag.Key) || A->QuestFlags[Flag.Key] != Flag.Value)
|
||||||
@ -43,5 +47,27 @@ bool UQuest::WorldStateMatch(UWorldState* A, UWorldState* B)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UQuest::FlagTrueMatch(const UWorldState* WorldState, const FString& FlagName)
|
||||||
|
{
|
||||||
|
if (!WorldState->QuestFlags.Contains(FlagName)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FString UQuest::GetItemCountAndGoalAmount(const UWorldState* WorldState, UBaseItem* Item) const
|
||||||
|
{
|
||||||
|
FString Result;
|
||||||
|
if (WorldState->Items.Contains(Item))
|
||||||
|
{
|
||||||
|
Result += FString::FromInt(WorldState->Items[WorldState->Items.Find(Item)]->StackCount);
|
||||||
|
Result += "/";
|
||||||
|
Result += FString::FromInt(Goals->Items[Goals->Items.Find(Item)]->StackCount);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
Result += "0/";
|
||||||
|
Result += FString::FromInt(Goals->Items[Goals->Items.Find(Item)]->StackCount);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
@ -31,11 +31,15 @@ public:
|
|||||||
UWorldState* Goals;
|
UWorldState* Goals;
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Instanced)
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Instanced)
|
||||||
UWorldState* PreConditions;
|
UWorldState* PreConditions;
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, NoClear, Instanced)
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Instanced)
|
||||||
TArray<UBaseItem*> Rewards;
|
TArray<UBaseItem*> Rewards;
|
||||||
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||||
|
bool bShowQuestCompletedNotification = true;
|
||||||
|
|
||||||
bool CheckConditions(UWorldState* WorldState) const;
|
bool CheckConditions(UWorldState* WorldState) const;
|
||||||
bool CheckPreConditions(UWorldState* WorldState) const;
|
bool CheckPreConditions(UWorldState* WorldState) const;
|
||||||
void ApplyRewards(UInventoryComponent* Inventory);
|
void ApplyRewards(UInventoryComponent* Inventory);
|
||||||
static bool WorldStateMatch(UWorldState* A, UWorldState* B);
|
static bool WorldStateMatch(UWorldState* A, UWorldState* B);
|
||||||
|
static bool FlagTrueMatch(const UWorldState* WorldState, const FString& FlagName);
|
||||||
|
FString GetItemCountAndGoalAmount(const UWorldState* WorldState, UBaseItem* Item) const;
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "QuestSystem.h"
|
#include "QuestSystem.h"
|
||||||
|
#include "Misc/OutputDeviceNull.h"
|
||||||
|
|
||||||
|
|
||||||
// Sets default values for this component's properties
|
// Sets default values for this component's properties
|
||||||
@ -13,6 +14,8 @@ UQuestSystem::UQuestSystem()
|
|||||||
|
|
||||||
static ConstructorHelpers::FClassFinder<UUserWidget> QuestWidgetClass(TEXT("/Game/Blueprints/Quest_UI/Quest_UI"));
|
static ConstructorHelpers::FClassFinder<UUserWidget> QuestWidgetClass(TEXT("/Game/Blueprints/Quest_UI/Quest_UI"));
|
||||||
QuestWidget = QuestWidgetClass.Class;
|
QuestWidget = QuestWidgetClass.Class;
|
||||||
|
static ConstructorHelpers::FClassFinder<UUserWidget> QuestCompletionWidgetClass(TEXT("/Game/Blueprints/Quest_UI/QuestCompletion_UI"));
|
||||||
|
QuestCompletionWidget = QuestCompletionWidgetClass.Class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -22,6 +25,24 @@ void UQuestSystem::BeginPlay()
|
|||||||
Super::BeginPlay();
|
Super::BeginPlay();
|
||||||
PlayerInventory = GetOwner()->FindComponentByClass<UInventoryComponent>();
|
PlayerInventory = GetOwner()->FindComponentByClass<UInventoryComponent>();
|
||||||
PlayerInventory->OnInventoryUpdated.AddDynamic(this, &UQuestSystem::CheckActiveQuestConditions);
|
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]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -40,7 +61,20 @@ void UQuestSystem::CheckActiveQuestConditions()
|
|||||||
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Quest Completed!"));
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Quest Completed!"));
|
||||||
CompletedQuests.Add(Quest);
|
CompletedQuests.Add(Quest);
|
||||||
Quest->ApplyRewards(PlayerInventory);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,6 +90,18 @@ bool UQuestSystem::AddQuest(UQuest* Quest)
|
|||||||
{
|
{
|
||||||
if (!Quest->CheckPreConditions(GetWorldState())) return false;
|
if (!Quest->CheckPreConditions(GetWorldState())) return false;
|
||||||
ActiveQuests.Add(Quest);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,3 +122,40 @@ bool UQuestSystem::HasActiveQuest(UQuest* Quest) const
|
|||||||
if (ActiveQuests.Contains(Quest)) return true;
|
if (ActiveQuests.Contains(Quest)) return true;
|
||||||
return false;
|
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));
|
||||||
|
}
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include "Quest.h"
|
#include "Quest.h"
|
||||||
#include "WorldState.h"
|
#include "WorldState.h"
|
||||||
#include "../BaseItems/InventoryComponent.h"
|
#include "../BaseItems/InventoryComponent.h"
|
||||||
|
#include "Components/Border.h"
|
||||||
|
#include "Components/RichTextBlock.h"
|
||||||
#include "QuestSystem.generated.h"
|
#include "QuestSystem.generated.h"
|
||||||
|
|
||||||
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
|
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
|
||||||
@ -27,12 +29,21 @@ public:
|
|||||||
UPROPERTY(EditAnywhere)
|
UPROPERTY(EditAnywhere)
|
||||||
TMap<FString, bool> QuestFlags;
|
TMap<FString, bool> QuestFlags;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
|
||||||
|
bool bHasSubQuest = false;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Called when the game starts
|
// Called when the game starts
|
||||||
virtual void BeginPlay() override;
|
virtual void BeginPlay() override;
|
||||||
|
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
TSubclassOf<UUserWidget> QuestWidget;
|
TSubclassOf<UUserWidget> QuestWidget;
|
||||||
|
UPROPERTY()
|
||||||
|
UUserWidget* QuestWidgetInstance;
|
||||||
|
UPROPERTY()
|
||||||
|
TSubclassOf<UUserWidget> QuestCompletionWidget;
|
||||||
|
UPROPERTY()
|
||||||
|
UUserWidget* QuestCompletionWidgetInstance;
|
||||||
|
|
||||||
FJsonObject WorldStateJsonTemplate;
|
FJsonObject WorldStateJsonTemplate;
|
||||||
|
|
||||||
@ -53,4 +64,24 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
UInventoryComponent* PlayerInventory;
|
UInventoryComponent* PlayerInventory;
|
||||||
|
|
||||||
|
// Quest Widget
|
||||||
|
UPROPERTY()
|
||||||
|
UBorder* MainQuestBorder;
|
||||||
|
UPROPERTY()
|
||||||
|
UBorder* SubQuestBorder;
|
||||||
|
UPROPERTY()
|
||||||
|
UTextBlock* MainQuestTitle;
|
||||||
|
UPROPERTY()
|
||||||
|
UTextBlock* SubQuestTitle;
|
||||||
|
UPROPERTY()
|
||||||
|
URichTextBlock* MainQuestGoals;
|
||||||
|
UPROPERTY()
|
||||||
|
URichTextBlock* SubQuestGoals;
|
||||||
|
|
||||||
|
// Quest Completion Widget
|
||||||
|
UPROPERTY()
|
||||||
|
UTextBlock* QuestCompletionTitle;
|
||||||
|
|
||||||
|
void UpdateQuestGoalsUI(const UQuest* Quest) const;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user