diff --git a/Content/Blueprints/Combat_UI/CombatCharacter.uasset b/Content/Blueprints/Combat_UI/CombatCharacter.uasset index 6099ffa..155172e 100644 --- a/Content/Blueprints/Combat_UI/CombatCharacter.uasset +++ b/Content/Blueprints/Combat_UI/CombatCharacter.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a7437070c9f3bb65f9fd9d77cec30f886ca9f39ae2aa8d03e805d16c9a5a1ad6 -size 159760 +oid sha256:9b8b8f32b2eb36e234605977e47dc74fd8b69113857b48d10f6c41c43752c4b0 +size 174740 diff --git a/Content/Blueprints/Quest_UI/QuestCompletion_UI.uasset b/Content/Blueprints/Quest_UI/QuestCompletion_UI.uasset new file mode 100644 index 0000000..9d262f9 --- /dev/null +++ b/Content/Blueprints/Quest_UI/QuestCompletion_UI.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ade73cd5549a847781ff42f9238f5e8e722cbc1b28347beb41a0e551942e479a +size 63404 diff --git a/Content/Blueprints/Quest_UI/Quest_UI.uasset b/Content/Blueprints/Quest_UI/Quest_UI.uasset index d49043e..4402f17 100644 --- a/Content/Blueprints/Quest_UI/Quest_UI.uasset +++ b/Content/Blueprints/Quest_UI/Quest_UI.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:75147975224f3f37ceefd5770c3cb0c4200b9ccceb2e2dfa88037d375aa6dee8 -size 46315 +oid sha256:eff7d76ef619408cc8b3b95782ea54d539a4fdb617ae3e0a38b0e04f3d9bce11 +size 46490 diff --git a/Content/Blueprints/Quests/Quest_SistersPendant.uasset b/Content/Blueprints/Quests/Quest_SistersPendant.uasset index d2fe7e3..4e4e76c 100644 --- a/Content/Blueprints/Quests/Quest_SistersPendant.uasset +++ b/Content/Blueprints/Quests/Quest_SistersPendant.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f424e061a8f4889a4942c0fced4329eaa79c9b6f6090c5242c75d92488e7031 -size 6835 +oid sha256:3beb11e9f1d958aa30d7f660b5ab50181189487f21515d03411ec02ec05873c2 +size 6849 diff --git a/Content/Blueprints/Quests/Quest_Start.uasset b/Content/Blueprints/Quests/Quest_Start.uasset index c6cb680..092b402 100644 --- a/Content/Blueprints/Quests/Quest_Start.uasset +++ b/Content/Blueprints/Quests/Quest_Start.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:24083ce082d9ee2d3ee3999793f3d511279e2c90fae0f31197cdb07cf43b72c7 +oid sha256:89735b36476f8030ece4bb83cb0e4e63c6a99ff5a3c3662ead9438c60ae0e157 size 7432 diff --git a/Content/Blueprints/Quests/Quest_Start2.uasset b/Content/Blueprints/Quests/Quest_Start2.uasset new file mode 100644 index 0000000..1904f41 --- /dev/null +++ b/Content/Blueprints/Quests/Quest_Start2.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac0470690e221af154467d6d311c9e7d5587302c01c2f6b69fd0a82cfa85c092 +size 7488 diff --git a/Content/Dialogue/SM_Merchant_Blueprint.uasset b/Content/Dialogue/SM_Merchant_Blueprint.uasset index 73d3e78..c27808c 100644 --- a/Content/Dialogue/SM_Merchant_Blueprint.uasset +++ b/Content/Dialogue/SM_Merchant_Blueprint.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4e595b95daa285ae1f4343aaaa303bd957f2ea9cfdd4f1c9841afa099e2543a5 -size 87521 +oid sha256:bee8f1aea1e8cbb574f4cbf9eec05ddf145d5c4150504e2cd34d35f03008e06d +size 86863 diff --git a/Content/Fonts/DT_RichText.uasset b/Content/Fonts/DT_RichText.uasset new file mode 100644 index 0000000..be6e48c --- /dev/null +++ b/Content/Fonts/DT_RichText.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04ca261e1c87d84d8dab5e22f265e848ad11d7478722388aa4f8b19ca706f4f0 +size 13718 diff --git a/Content/Levels/Testing/BreakableWall_BP_ExitCave.uasset b/Content/Levels/Testing/BreakableWall_BP_ExitCave.uasset new file mode 100644 index 0000000..ffb34e2 --- /dev/null +++ b/Content/Levels/Testing/BreakableWall_BP_ExitCave.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f1364ebf56c0b6f70179e9512dcbe6cf39cb4e98e51c4c7bdf07e7a3eee32f8 +size 95512 diff --git a/Source/the_twilight_abyss/Quest/Quest.cpp b/Source/the_twilight_abyss/Quest/Quest.cpp index b73f48d..bb1c201 100644 --- a/Source/the_twilight_abyss/Quest/Quest.cpp +++ b/Source/the_twilight_abyss/Quest/Quest.cpp @@ -21,6 +21,7 @@ bool UQuest::CheckPreConditions(UWorldState* WorldState) const void UQuest::ApplyRewards(UInventoryComponent* Inventory) { + if (Rewards.IsEmpty()) return; for (UBaseItem* Item : Rewards) { Inventory->AddItem(Item); @@ -29,6 +30,7 @@ void UQuest::ApplyRewards(UInventoryComponent* Inventory) bool UQuest::WorldStateMatch(UWorldState* A, UWorldState* B) { + if (A->Items.IsEmpty() && !B->Items.IsEmpty()) return false; for (UBaseItem* Item : B->Items) { 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; } } + + if (A->QuestFlags.IsEmpty() && !B->QuestFlags.IsEmpty()) return false; for (TTuple Flag : B->QuestFlags) { 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 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; +} diff --git a/Source/the_twilight_abyss/Quest/Quest.h b/Source/the_twilight_abyss/Quest/Quest.h index e2e3659..b9e27c5 100644 --- a/Source/the_twilight_abyss/Quest/Quest.h +++ b/Source/the_twilight_abyss/Quest/Quest.h @@ -31,11 +31,15 @@ public: UWorldState* Goals; UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Instanced) UWorldState* PreConditions; - UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, NoClear, Instanced) + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Instanced) TArray Rewards; + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) + bool bShowQuestCompletedNotification = true; bool CheckConditions(UWorldState* WorldState) const; bool CheckPreConditions(UWorldState* WorldState) const; void ApplyRewards(UInventoryComponent* Inventory); static bool WorldStateMatch(UWorldState* A, UWorldState* B); + static bool FlagTrueMatch(const UWorldState* WorldState, const FString& FlagName); + FString GetItemCountAndGoalAmount(const UWorldState* WorldState, UBaseItem* Item) const; }; diff --git a/Source/the_twilight_abyss/Quest/QuestSystem.cpp b/Source/the_twilight_abyss/Quest/QuestSystem.cpp index 9087ac5..6994bf9 100644 --- a/Source/the_twilight_abyss/Quest/QuestSystem.cpp +++ b/Source/the_twilight_abyss/Quest/QuestSystem.cpp @@ -2,6 +2,7 @@ #include "QuestSystem.h" +#include "Misc/OutputDeviceNull.h" // Sets default values for this component's properties @@ -13,6 +14,8 @@ UQuestSystem::UQuestSystem() static ConstructorHelpers::FClassFinder QuestWidgetClass(TEXT("/Game/Blueprints/Quest_UI/Quest_UI")); QuestWidget = QuestWidgetClass.Class; + static ConstructorHelpers::FClassFinder QuestCompletionWidgetClass(TEXT("/Game/Blueprints/Quest_UI/QuestCompletion_UI")); + QuestCompletionWidget = QuestCompletionWidgetClass.Class; } @@ -22,6 +25,24 @@ void UQuestSystem::BeginPlay() Super::BeginPlay(); PlayerInventory = GetOwner()->FindComponentByClass(); PlayerInventory->OnInventoryUpdated.AddDynamic(this, &UQuestSystem::CheckActiveQuestConditions); + QuestWidgetInstance = CreateWidget(GetWorld(), QuestWidget); + QuestWidgetInstance->AddToViewport(); + QuestCompletionWidgetInstance = CreateWidget(GetWorld(), QuestCompletionWidget); + QuestCompletionWidgetInstance->AddToViewport(); + + MainQuestBorder = Cast(QuestWidgetInstance->GetWidgetFromName("MainQuest")); + SubQuestBorder = Cast(QuestWidgetInstance->GetWidgetFromName("SubQuest")); + MainQuestTitle = Cast(QuestWidgetInstance->GetWidgetFromName("MainQuest_Text")); + SubQuestTitle = Cast(QuestWidgetInstance->GetWidgetFromName("SubQuest_Text")); + MainQuestGoals = Cast(QuestWidgetInstance->GetWidgetFromName("MainGoals_Text")); + SubQuestGoals = Cast(QuestWidgetInstance->GetWidgetFromName("SubGoals_Text")); + + QuestCompletionTitle = Cast(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!")); 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); } } @@ -56,6 +90,18 @@ bool UQuestSystem::AddQuest(UQuest* Quest) { 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; } @@ -76,3 +122,40 @@ 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 QuestFlag : Quest->Goals->QuestFlags) + { + if (Quest->FlagTrueMatch(GetWorldState(), QuestFlag.Key)) + { + GoalsText += FString::Printf(TEXT("- %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("- %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)); +} diff --git a/Source/the_twilight_abyss/Quest/QuestSystem.h b/Source/the_twilight_abyss/Quest/QuestSystem.h index 0a04290..9dd8407 100644 --- a/Source/the_twilight_abyss/Quest/QuestSystem.h +++ b/Source/the_twilight_abyss/Quest/QuestSystem.h @@ -9,6 +9,8 @@ #include "Quest.h" #include "WorldState.h" #include "../BaseItems/InventoryComponent.h" +#include "Components/Border.h" +#include "Components/RichTextBlock.h" #include "QuestSystem.generated.h" UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent)) @@ -27,12 +29,21 @@ public: UPROPERTY(EditAnywhere) TMap QuestFlags; + UPROPERTY(VisibleAnywhere, BlueprintReadOnly) + bool bHasSubQuest = false; + protected: // Called when the game starts virtual void BeginPlay() override; UPROPERTY() TSubclassOf QuestWidget; + UPROPERTY() + UUserWidget* QuestWidgetInstance; + UPROPERTY() + TSubclassOf QuestCompletionWidget; + UPROPERTY() + UUserWidget* QuestCompletionWidgetInstance; FJsonObject WorldStateJsonTemplate; @@ -53,4 +64,24 @@ public: private: 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; };