diff --git a/Content/Character/BP_BaseCharacter_Template.uasset b/Content/Character/BP_BaseCharacter_Template.uasset index bd6deea8..1d2ff6c9 100644 --- a/Content/Character/BP_BaseCharacter_Template.uasset +++ b/Content/Character/BP_BaseCharacter_Template.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5344a25c6577b8c91998fabc1d319dcd11abade0cfe593c1fd79d1e8008dbee0 -size 44912 +oid sha256:70231cafa5f18bfbca9eb0760dd80d4f917ad5a4b36cc6a1ddd6d1b45629388e +size 45440 diff --git a/Content/Scripts/AlchemySystem/BP_AlchemyManager.uasset b/Content/Scripts/AlchemySystem/BP_AlchemyManager.uasset index b1393fd5..0f9403dd 100644 --- a/Content/Scripts/AlchemySystem/BP_AlchemyManager.uasset +++ b/Content/Scripts/AlchemySystem/BP_AlchemyManager.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:61afa506ffd24ce297ff2b5f18cf56c582a5e121700759f24ace77fe1f1b3be7 -size 2825394 +oid sha256:0495ce288d67ba11d327dfe183f7e99cb4ebbb7f7ff7d07eef257e25a3ef2c39 +size 2837751 diff --git a/Content/Scripts/Bazar/BP_BazarSellingStand.uasset b/Content/Scripts/Bazar/BP_BazarSellingStand.uasset index 2c087708..b5138680 100644 --- a/Content/Scripts/Bazar/BP_BazarSellingStand.uasset +++ b/Content/Scripts/Bazar/BP_BazarSellingStand.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e61e96bc45f0c4d9cfd459a48398430f83a55ac06db4d0852016d82f8693e824 -size 468991 +oid sha256:b56ecde6cb227b34d77b8e33cef0f0ea3e9b9446621741ad56b1f79584477672 +size 467587 diff --git a/Content/Scripts/DialogueSystem/DialogueManager.uasset b/Content/Scripts/DialogueSystem/DialogueManager.uasset index 530d867c..4cb7bebc 100644 --- a/Content/Scripts/DialogueSystem/DialogueManager.uasset +++ b/Content/Scripts/DialogueSystem/DialogueManager.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e95191a3d7a5f044d452ecdcab63f2c1108995c5ff70f9fdf4674c3e9c4b9f12 -size 631218 +oid sha256:2563e522d14a364019e9d81d519ea1d2f43f58ad35e357e2092084c78817098d +size 42542 diff --git a/Content/Scripts/DialogueSystem/UI/DialogueScreen.uasset b/Content/Scripts/DialogueSystem/UI/DialogueScreen.uasset index bc8d618f..ccc7bec6 100644 --- a/Content/Scripts/DialogueSystem/UI/DialogueScreen.uasset +++ b/Content/Scripts/DialogueSystem/UI/DialogueScreen.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:38b7edf6c68a1b7d4cace285176b061fc39e5cb910af6441c9109893ca7692f1 -size 586567 +oid sha256:bd00b51148b74a601c28507602016fbbd291c1acf083d295c949d5398a2f98ec +size 585810 diff --git a/Content/Scripts/InventorySystem/MerchantBP.uasset b/Content/Scripts/InventorySystem/MerchantBP.uasset index 8603a4d3..9cd6724d 100644 --- a/Content/Scripts/InventorySystem/MerchantBP.uasset +++ b/Content/Scripts/InventorySystem/MerchantBP.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9ac7e43db40f1c45683251d9444c858d7a76ce45b1374d7a5057fc04d9e1accf -size 316412 +oid sha256:3f1f72a622ba209b38f7094964dc7e67da1faff32292b13f53a3b5e205f5f1fc +size 335190 diff --git a/Content/Scripts/InventorySystem/Seed/BP_SeedCarousel.uasset b/Content/Scripts/InventorySystem/Seed/BP_SeedCarousel.uasset index bf9cc3a7..f7943dea 100644 --- a/Content/Scripts/InventorySystem/Seed/BP_SeedCarousel.uasset +++ b/Content/Scripts/InventorySystem/Seed/BP_SeedCarousel.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ebbac205e29c7e473f3d69f22365b5ca4f5eb69fd44ba93f9fdd0a9fad0055d0 -size 1246962 +oid sha256:60bd5caafa271411d9e172d32d42f671861bd413306881208f6bb9378af7dc8d +size 1043487 diff --git a/Content/Scripts/MODULES/UI_DialogueOptionModule.uasset b/Content/Scripts/MODULES/UI_DialogueOptionModule.uasset index 6d374ba0..e73cc49e 100644 --- a/Content/Scripts/MODULES/UI_DialogueOptionModule.uasset +++ b/Content/Scripts/MODULES/UI_DialogueOptionModule.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4665a31648bbff6b50324bf8d361793a3fae6a9dcfa6708219d486e1aed4e14d -size 96736 +oid sha256:b5abeeae27081fb4abc7171cc806831075547b20713a9819bda4a62e2050579f +size 91195 diff --git a/Content/Scripts/Tutorial/BP_TutorialManager.uasset b/Content/Scripts/Tutorial/BP_TutorialManager.uasset index d733536e..43c8d2c5 100644 --- a/Content/Scripts/Tutorial/BP_TutorialManager.uasset +++ b/Content/Scripts/Tutorial/BP_TutorialManager.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6dc95e7b0aa3c6a8f22ceb3258f820c1d29aaca59a08f7dc8be44175759b0c7d -size 311627 +oid sha256:3c8fb11cf7e807164a9064535fcc11b86f3950ce3725dfef0623f2a03d6227f1 +size 314069 diff --git a/Source/ProjectEleri/DialogueSystem/DialogueComponent.cpp b/Source/ProjectEleri/DialogueSystem/DialogueComponent.cpp index 4bc08340..520d8607 100644 --- a/Source/ProjectEleri/DialogueSystem/DialogueComponent.cpp +++ b/Source/ProjectEleri/DialogueSystem/DialogueComponent.cpp @@ -4,22 +4,15 @@ #include "DialogueComponent.h" #include "DialogueSubsystem.h" -#include "Components/WidgetComponent.h" #include "DialogueWidget.h" +#include "EleriPlayerController.h" +#include "Speech.h" #include "SpeechDataAsset.h" #include "Kismet/GameplayStatics.h" +#include "ProjectEleri/GameEventSystem/GameEventSubsystem.h" +#define LOCTEXT_NAMESPACE "DialogueSystem" -// Sets default values for this component's properties -UDialogueComponent::UDialogueComponent() -{ - // 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; - -} - -// Called when the game starts void UDialogueComponent::BeginPlay() { Super::BeginPlay(); @@ -37,6 +30,7 @@ void UDialogueComponent::BeginPlay() } } + EleriPlayerController = Cast(UGameplayStatics::GetPlayerController(this, 0)); } void UDialogueComponent::OnDialogueLoaded() @@ -48,14 +42,6 @@ void UDialogueComponent::OnDialogueLoaded() } } -// Called every frame -void UDialogueComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) -{ - Super::TickComponent(DeltaTime, TickType, ThisTickFunction); - - // ... -} - void UDialogueComponent::FilterSpeechData() { ActiveSpeechData.Empty(); @@ -66,6 +52,59 @@ void UDialogueComponent::FilterSpeechData() } } +void UDialogueComponent::StartDialogueWithNpc() +{ + UDialogueSubsystem* DialogueSubsystem = UDialogueSubsystem::Get(this); + ensure(DialogueSubsystem); + + if (!DialogueSubsystem->StartDialogue()) return; + + MappedDialogueOptions.Empty(); + FilterSpeechData(); + TArray StartingDialogues = GetStartingDialogues(); + if (StartingDialogues.IsEmpty()) return; + + TriggerDialogue(StartingDialogues[FMath::RandRange(0, StartingDialogues.Num() - 1)], CurrentDialogueReplacementMap); + + TArray ActiveDialogues = GetActiveDialogues(); + TArray PlayerAsks = GetPlayerAsksFromDialogueList(ActiveDialogues); + for (int32 i = 0; i < ActiveDialogues.Num() - 1; i++) + { + FPlayerSpeakToDialogue SpeakToDialogue; + SpeakToDialogue.NextSpeechDataAsset = ActiveDialogues[i]; + MappedDialogueOptions.Add(i, SpeakToDialogue); + } + TriggerDialogueSelect(PlayerAsks, true); +} + +void UDialogueComponent::TriggerDialogue_Async(TSoftObjectPtr DialogueAssetPath, const TMap& ReplacementMap) +{ + DialogueAssetPath.LoadAsync(FLoadSoftObjectPathAsyncDelegate::CreateWeakLambda(this, [this, ReplacementMap](const FSoftObjectPath& Path, UObject* Object) + { + if (USpeechDataAsset* DataAsset = Cast(Object)) + { + TriggerDialogue(DataAsset, ReplacementMap); + } + })); +} + +void UDialogueComponent::TriggerDialogue(USpeechDataAsset* DialogueAssetPath, const TMap& ReplacementMap) +{ + UDialogueSubsystem* DialogueSubsystem = UDialogueSubsystem::Get(this); + if (!DialogueSubsystem) return; + + if (!DialogueSubsystem->StartDialogue()) return; + + BindToControllerInput(); + bDialogueSelectOpen = false; + DialogueWidget = Cast(EleriPlayerController->ToggleDialogueWindow(true)); + DialogueWidget->AssignDialogueComponent(this); + CurrentLineIndex = 0; + CurrentActiveDialogue = DialogueAssetPath; + CurrentDialogueReplacementMap = ReplacementMap; + DialogueWidget->DisplayDialogue(CurrentActiveDialogue, GetOwner(), CurrentDialogueReplacementMap); +} + TArray UDialogueComponent::GetActiveSpeechData() { return ActiveSpeechData; } TArray UDialogueComponent::GetStartingDialogues() @@ -92,4 +131,130 @@ TArray UDialogueComponent::GetActiveDialogues() return TempSpeechData; } +void UDialogueComponent::SetTextReplacementMap(const TMap& ReplacementMap) +{ + CurrentDialogueReplacementMap = ReplacementMap; +} + +void UDialogueComponent::CloseDialogue() +{ + UDialogueSubsystem* DialogueSubsystem = UDialogueSubsystem::Get(this); + if (!DialogueSubsystem) return; + DialogueSubsystem->EndDialogue(); + + SelectedDialogueOptionIndex = 0; + CurrentLineIndex = 0; + CurrentActiveDialogue = nullptr; + UnbindControllerInput(); + EleriPlayerController->ToggleDialogueWindow(false); +} + +void UDialogueComponent::AdvanceDialogue() +{ + const UDialogueSubsystem* DialogueSubsystem = UDialogueSubsystem::Get(this); + if (!DialogueSubsystem) return; + + if (!DialogueWidget) return; + + if (CurrentActiveDialogue) + { + if (bDialogueSelectOpen) return; + + if (DialogueWidget->IsTypingDialogue()) + { + DialogueWidget->SkipDialogueTyping(); + return; + } + + const FSoftObjectPath EventToTrigger = CurrentActiveDialogue->DialogueLines[CurrentLineIndex].TriggerEventStart; + if (!EventToTrigger.IsNull()) + { + UGameEventSubsystem::GetGameEventSubsystem()->StartEvent(EventToTrigger); + } + + if (CurrentLineIndex < CurrentActiveDialogue->DialogueLines.Num() - 1) + { + CurrentLineIndex++; + DialogueWidget->AdvanceDialogue(CurrentActiveDialogue->DialogueLines[CurrentLineIndex].DialogueLine, CurrentActiveDialogue->DialogueLines[CurrentLineIndex].SpeakerName); + return; + } + + if (!CurrentActiveDialogue->PlayerSpeechMap.IsEmpty()) + { + MappedDialogueOptions.Empty(); + TArray PlayerSpeakOptions; + for (int32 i = 0; i < CurrentActiveDialogue->PlayerSpeechMap.Num() - 1; i++) + { + MappedDialogueOptions.Add(i, CurrentActiveDialogue->PlayerSpeechMap[i]); + PlayerSpeakOptions.Add(CurrentActiveDialogue->PlayerSpeechMap[i].PlayerSpeak); + } + TriggerDialogueSelect(PlayerSpeakOptions, false); + return; + } + } + + CloseDialogue(); + DialogueSubsystem->OnDialogueEnded.Broadcast(); +} + +void UDialogueComponent::TriggerDialogueSelect(TArray& DialogueOptions, bool bIsDialogueStart) +{ + if (DialogueOptions.IsEmpty()) return; + + if (bIsDialogueStart) + { + DialogueOptions.Add(LOCTEXT("Bye_DialogueEnd", "Bye")); + } + + DialogueWidget->OnDialogueOptionSelected.AddUniqueDynamic(this, &UDialogueComponent::OnDialogueOptionSelected); + bDialogueSelectOpen = true; + SelectedDialogueOptionIndex = 0; + DialogueWidget->ShowDialogueOptions(true, DialogueOptions); +} + +void UDialogueComponent::OnDialogueOptionSelected(int32 Index) +{ + DialogueWidget->OnDialogueOptionSelected.RemoveDynamic(this, &UDialogueComponent::OnDialogueOptionSelected); + SelectedDialogueOptionIndex = Index; + + if (const FPlayerSpeakToDialogue* PlayerSpeak = MappedDialogueOptions.Find(SelectedDialogueOptionIndex)) + { + if (PlayerSpeak->GameplayTag.IsValid()) + { + UDialogueSubsystem::Get(this)->OnDialogueGameplayEvent.Broadcast(PlayerSpeak->GameplayTag); + } + + if(!PlayerSpeak->NextSpeechDataAsset.IsNull()) + { + TriggerDialogue_Async(PlayerSpeak->NextSpeechDataAsset, CurrentDialogueReplacementMap); + return; + } + } + + CloseDialogue(); +} + +TArray UDialogueComponent::GetPlayerAsksFromDialogueList(const TArray& DialogueList) +{ + TArray PlayerAsks; + for (const USpeechDataAsset* DataAsset : DialogueList) + { + PlayerAsks.Add(DataAsset->PlayerAsk); + } + + return PlayerAsks; +} + +TArray UDialogueComponent::GetDialogueOptionsFromPlayerSpeakList(const TArray& SpeakList) +{ + TArray Options; + for (const FPlayerSpeakToDialogue& Speak : SpeakList) + { + Options.Add(Speak.PlayerSpeak); + } + + return Options; +} + +#undef LOCTEXT_NAMESPACE diff --git a/Source/ProjectEleri/DialogueSystem/DialogueComponent.h b/Source/ProjectEleri/DialogueSystem/DialogueComponent.h index 22e3da20..6181930d 100644 --- a/Source/ProjectEleri/DialogueSystem/DialogueComponent.h +++ b/Source/ProjectEleri/DialogueSystem/DialogueComponent.h @@ -4,10 +4,12 @@ #include "CoreMinimal.h" #include "Components/ActorComponent.h" +#include "ProjectEleri/DialogueSystem/SpeechDataAsset.h" #include "DialogueComponent.generated.h" -class USpeechDataAsset; +struct FPlayerSpeakToDialogue; +class AEleriPlayerController; class UDialogueWidget; class UWidgetComponent; @@ -17,32 +19,54 @@ class PROJECTELERI_API UDialogueComponent : public UActorComponent GENERATED_BODY() public: - // Sets default values for this component's properties - UDialogueComponent(); - -public: - // Called every frame - virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; - - UFUNCTION(BlueprintCallable) + UFUNCTION(BlueprintCallable, Category = "Eleri|Dialogue") void FilterSpeechData(); + + // use when you want to chit chat with an npc instead of play a specific dialogue option + UFUNCTION(BlueprintCallable, Category = "Eleri|Dialogue") + void StartDialogueWithNpc(); + UFUNCTION(BlueprintCallable, Category = "Eleri|Dialogue", meta = (AutoCreateRefTerm = "ReplacementMap")) + void TriggerDialogue_Async(TSoftObjectPtr DialogueAssetPath, const TMap& ReplacementMap); + UFUNCTION(BlueprintCallable, Category = "Eleri|Dialogue", meta = (AutoCreateRefTerm = "ReplacementMap")) + void TriggerDialogue(USpeechDataAsset* DialogueAssetPath, const TMap& ReplacementMap); - UFUNCTION(BlueprintCallable) + UFUNCTION(BlueprintCallable, Category = "Eleri|Dialogue") TArray GetActiveSpeechData(); //Goes through active speech data and returns the all speech data asset without a condition and player ask - UFUNCTION(BlueprintCallable) + UFUNCTION(BlueprintCallable, Category = "Eleri|Dialogue") TArray GetStartingDialogues(); - UFUNCTION(BlueprintCallable) + UFUNCTION(BlueprintCallable, Category = "Eleri|Dialogue") TArray GetActiveDialogues(); + UFUNCTION(BlueprintCallable, Category = "Eleri|Dialogue") + void SetTextReplacementMap(const TMap& ReplacementMap); + protected: + + UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category = "Eleri|Dialogue") + void BindToControllerInput(); + UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category = "Eleri|Dialogue") + void UnbindControllerInput(); + UFUNCTION(BlueprintCallable, Category = "Eleri|Dialogue") + void CloseDialogue(); + UFUNCTION(BlueprintCallable, Category = "Eleri|Dialogue") + void AdvanceDialogue(); + UFUNCTION(BlueprintCallable, Category = "Eleri|Dialogue") + void TriggerDialogueSelect(TArray& DialogueOptions, bool bIsDialogueStart); + UFUNCTION() + void OnDialogueOptionSelected(int32 Index); + static TArray GetPlayerAsksFromDialogueList(const TArray& DialogueList); + static TArray GetDialogueOptionsFromPlayerSpeakList(const TArray& SpeakList); + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "DialogueWidget") TSubclassOf DialogueWidgetClass; UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) AActor* OwnerActor; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + AEleriPlayerController* EleriPlayerController; TObjectPtr DialogueWidgetComponent; UPROPERTY() @@ -54,6 +78,19 @@ protected: UPROPERTY() TArray> ActiveSpeechData; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + bool bDialogueSelectOpen = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + int32 CurrentLineIndex = 0; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + int32 SelectedDialogueOptionIndex = 0; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + USpeechDataAsset* CurrentActiveDialogue; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + TMap MappedDialogueOptions; + UPROPERTY() + TMap CurrentDialogueReplacementMap; + protected: // Called when the game starts virtual void BeginPlay() override; diff --git a/Source/ProjectEleri/DialogueSystem/DialogueSubsystem.cpp b/Source/ProjectEleri/DialogueSystem/DialogueSubsystem.cpp index 23c537f7..e72a179b 100644 --- a/Source/ProjectEleri/DialogueSystem/DialogueSubsystem.cpp +++ b/Source/ProjectEleri/DialogueSystem/DialogueSubsystem.cpp @@ -5,6 +5,17 @@ #include "SpeechDataAsset.h" #include "Engine/AssetManager.h" +#include "Kismet/GameplayStatics.h" + +UDialogueSubsystem* UDialogueSubsystem::Get(const UObject* WorldContext) +{ + if(const UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(WorldContext)) + { + return GameInstance->GetSubsystem(); + } + + return nullptr; +} void UDialogueSubsystem::Initialize(FSubsystemCollectionBase& Collection) { diff --git a/Source/ProjectEleri/DialogueSystem/DialogueSubsystem.h b/Source/ProjectEleri/DialogueSystem/DialogueSubsystem.h index 3b53e3a6..3746ee22 100644 --- a/Source/ProjectEleri/DialogueSystem/DialogueSubsystem.h +++ b/Source/ProjectEleri/DialogueSystem/DialogueSubsystem.h @@ -7,6 +7,8 @@ #include "DialogueSubsystem.generated.h" DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnDialogueAssetsLoaded); +DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnDialogueEnded); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnDialogueGameplayEvent, FGameplayTag, GameplayTag); class USpeechDataAsset; /** @@ -19,10 +21,15 @@ class PROJECTELERI_API UDialogueSubsystem : public UGameInstanceSubsystem public: - UPROPERTY(BlueprintAssignable) + UPROPERTY(BlueprintAssignable, Category = "Eleri|Dialogue") FOnDialogueAssetsLoaded OnDialogueAssetsLoaded; + UPROPERTY(BlueprintAssignable, BlueprintCallable, Category = "Eleri|Dialogue") + FOnDialogueEnded OnDialogueEnded; + UPROPERTY(BlueprintAssignable, BlueprintCallable, Category = "Eleri|Dialogue") + FOnDialogueGameplayEvent OnDialogueGameplayEvent; + + static UDialogueSubsystem* Get(const UObject* WorldContext); -public: virtual void Initialize(FSubsystemCollectionBase& Collection) override; bool IsDialogueLoaded() const { return bDialogueLoaded; } TArray> GetDialogueForActor(const AActor* Actor); diff --git a/Source/ProjectEleri/DialogueSystem/DialogueWidget.h b/Source/ProjectEleri/DialogueSystem/DialogueWidget.h index d55e330a..9513b23b 100644 --- a/Source/ProjectEleri/DialogueSystem/DialogueWidget.h +++ b/Source/ProjectEleri/DialogueSystem/DialogueWidget.h @@ -27,6 +27,8 @@ public: virtual void NativeOnInitialized() override; + bool IsTypingDialogue() const { return bIsTypingDialogue; } + protected: UPROPERTY(EditAnywhere, BlueprintReadWrite) bool bIsAnimating = false; @@ -51,11 +53,11 @@ protected: UPROPERTY(EditAnywhere, BlueprintReadWrite) int32 CurrentTypingDialogueIndex = 0; - - UPROPERTY(BlueprintAssignable, BlueprintReadWrite, BlueprintCallable) - FOnDialogueOptionSelected OnDialogueOptionSelected; + public: + void AssignDialogueComponent(UDialogueComponent* InDialogueComponent) { DialogueComponent = InDialogueComponent; } + UFUNCTION(BlueprintImplementableEvent, BlueprintCallable) void SetDialogueOptionsPadding(); @@ -82,5 +84,7 @@ public: UFUNCTION(BlueprintImplementableEvent, BlueprintCallable) void SetSpeakerName(const FText& NewSpeakerName); - + + UPROPERTY(BlueprintAssignable, BlueprintReadWrite, BlueprintCallable) + FOnDialogueOptionSelected OnDialogueOptionSelected; }; diff --git a/Source/ProjectEleri/Private/EleriPlayerController.cpp b/Source/ProjectEleri/Private/EleriPlayerController.cpp index 4f88db3f..013cb910 100644 --- a/Source/ProjectEleri/Private/EleriPlayerController.cpp +++ b/Source/ProjectEleri/Private/EleriPlayerController.cpp @@ -1103,10 +1103,10 @@ UEleriBaseWidget *AEleriPlayerController::ToggleAlchemyMenu(bool bOpen) UEleriBaseWidget *AEleriPlayerController::ToggleDialogueWindow(bool bOpen) { - if (!IsValid(MainGameUI->GetDialogueWidget()) || MainGameUI->GetDialogueWidget()->IsAnimating()) + if (!IsValid(MainGameUI->GetDialogueWidget())) return nullptr; - MainGameUI->OpenWidget(MainGameUI->GetDialogueWidget()); + bOpen? MainGameUI->OpenWidget(MainGameUI->GetDialogueWidget()) : MainGameUI->CloseWidget(MainGameUI->GetDialogueWidget()); return MainGameUI->GetDialogueWidget(); }