diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..1115f0d --- /dev/null +++ b/.editorconfig @@ -0,0 +1,2 @@ +[*.{c, cpp, h, hpp, cs}] +trim_trailing_whitespace = true \ No newline at end of file diff --git a/Content/Blueprints/Characters/BP_Player.uasset b/Content/Blueprints/Characters/BP_Player.uasset index 81f6837..5f28f18 100644 Binary files a/Content/Blueprints/Characters/BP_Player.uasset and b/Content/Blueprints/Characters/BP_Player.uasset differ diff --git a/Content/Input/Actions/IA_CutsceneSkip.uasset b/Content/Input/Actions/IA_CutsceneSkip.uasset index 8b8a181..03f9f77 100644 Binary files a/Content/Input/Actions/IA_CutsceneSkip.uasset and b/Content/Input/Actions/IA_CutsceneSkip.uasset differ diff --git a/Content/Input/Actions/IA_DialogueSkip.uasset b/Content/Input/Actions/IA_DialogueSkip.uasset new file mode 100644 index 0000000..b7bdca3 Binary files /dev/null and b/Content/Input/Actions/IA_DialogueSkip.uasset differ diff --git a/Content/Input/Actions/IA_Journal.uasset b/Content/Input/Actions/IA_Journal.uasset new file mode 100644 index 0000000..7728aba Binary files /dev/null and b/Content/Input/Actions/IA_Journal.uasset differ diff --git a/Content/Input/IMC_Dialogue.uasset b/Content/Input/IMC_Dialogue.uasset new file mode 100644 index 0000000..a962cb7 Binary files /dev/null and b/Content/Input/IMC_Dialogue.uasset differ diff --git a/Content/Input/IMC_Player.uasset b/Content/Input/IMC_Player.uasset index b416cb5..7982723 100644 Binary files a/Content/Input/IMC_Player.uasset and b/Content/Input/IMC_Player.uasset differ diff --git a/Content/Levels/Level_1/Blueprints/BP_TriggerBoxScene4Shadow.uasset b/Content/Levels/Level_1/Blueprints/BP_TriggerBoxScene4Shadow.uasset index 14db688..b7b3f39 100644 Binary files a/Content/Levels/Level_1/Blueprints/BP_TriggerBoxScene4Shadow.uasset and b/Content/Levels/Level_1/Blueprints/BP_TriggerBoxScene4Shadow.uasset differ diff --git a/Content/Levels/Level_1/L_Level1.umap b/Content/Levels/Level_1/L_Level1.umap index bd88259..8d269a0 100644 Binary files a/Content/Levels/Level_1/L_Level1.umap and b/Content/Levels/Level_1/L_Level1.umap differ diff --git a/Content/Levels/Test/Actors/CutsceneTest/BP_Test_CutsceneMultiple.uasset b/Content/Levels/Test/Actors/CutsceneTest/BP_Test_CutsceneMultiple.uasset index 61c8747..c963783 100644 Binary files a/Content/Levels/Test/Actors/CutsceneTest/BP_Test_CutsceneMultiple.uasset and b/Content/Levels/Test/Actors/CutsceneTest/BP_Test_CutsceneMultiple.uasset differ diff --git a/Content/Levels/Test/Actors/CutsceneTest/BP_Test_CutsceneSingle.uasset b/Content/Levels/Test/Actors/CutsceneTest/BP_Test_CutsceneSingle.uasset index 7cdc67c..6565067 100644 Binary files a/Content/Levels/Test/Actors/CutsceneTest/BP_Test_CutsceneSingle.uasset and b/Content/Levels/Test/Actors/CutsceneTest/BP_Test_CutsceneSingle.uasset differ diff --git a/Content/Levels/Test/Actors/DialogueTest/BP_Test_DialogueMain.uasset b/Content/Levels/Test/Actors/DialogueTest/BP_Test_DialogueMain.uasset new file mode 100644 index 0000000..f9126af Binary files /dev/null and b/Content/Levels/Test/Actors/DialogueTest/BP_Test_DialogueMain.uasset differ diff --git a/Content/Levels/Test/Actors/DialogueTest/BP_Test_DialogueSecondary.uasset b/Content/Levels/Test/Actors/DialogueTest/BP_Test_DialogueSecondary.uasset new file mode 100644 index 0000000..88cf0fd Binary files /dev/null and b/Content/Levels/Test/Actors/DialogueTest/BP_Test_DialogueSecondary.uasset differ diff --git a/Content/Levels/Test/L_Test.umap b/Content/Levels/Test/L_Test.umap index 8612627..b99fa9a 100644 Binary files a/Content/Levels/Test/L_Test.umap and b/Content/Levels/Test/L_Test.umap differ diff --git a/Content/Levels/Test/Other/Dialogue/DT_Test_DialogueMain.uasset b/Content/Levels/Test/Other/Dialogue/DT_Test_DialogueMain.uasset new file mode 100644 index 0000000..291ba3c Binary files /dev/null and b/Content/Levels/Test/Other/Dialogue/DT_Test_DialogueMain.uasset differ diff --git a/Content/Levels/Test/Other/Dialogue/SW_Test_Dialogue.uasset b/Content/Levels/Test/Other/Dialogue/SW_Test_Dialogue.uasset new file mode 100644 index 0000000..91a7214 Binary files /dev/null and b/Content/Levels/Test/Other/Dialogue/SW_Test_Dialogue.uasset differ diff --git a/Content/UI/BP_MainWidgetManager.uasset b/Content/UI/BP_MainWidgetManager.uasset index 85cf968..a0fcdf3 100644 Binary files a/Content/UI/BP_MainWidgetManager.uasset and b/Content/UI/BP_MainWidgetManager.uasset differ diff --git a/Content/UI/Blueprints/Dialogues/UI_DialogueManager.uasset b/Content/UI/Blueprints/Dialogues/UI_DialogueManager.uasset new file mode 100644 index 0000000..84445e2 Binary files /dev/null and b/Content/UI/Blueprints/Dialogues/UI_DialogueManager.uasset differ diff --git a/Content/UI/Blueprints/Dialogues/UI_DialogueRow.uasset b/Content/UI/Blueprints/Dialogues/UI_DialogueRow.uasset new file mode 100644 index 0000000..da010bf Binary files /dev/null and b/Content/UI/Blueprints/Dialogues/UI_DialogueRow.uasset differ diff --git a/Content/UI/Blueprints/Dialogues/UI_DialogueSkip.uasset b/Content/UI/Blueprints/Dialogues/UI_DialogueSkip.uasset new file mode 100644 index 0000000..637e3ce Binary files /dev/null and b/Content/UI/Blueprints/Dialogues/UI_DialogueSkip.uasset differ diff --git a/Content/UI/Blueprints/UI_Inventory.uasset b/Content/UI/Blueprints/UI_Inventory.uasset index bec9ff0..8a64754 100644 Binary files a/Content/UI/Blueprints/UI_Inventory.uasset and b/Content/UI/Blueprints/UI_Inventory.uasset differ diff --git a/Content/UI/Blueprints/UI_Journal.uasset b/Content/UI/Blueprints/UI_Journal.uasset new file mode 100644 index 0000000..98adeef Binary files /dev/null and b/Content/UI/Blueprints/UI_Journal.uasset differ diff --git a/Content/UI/Components/UIC_JournalText.uasset b/Content/UI/Components/UIC_JournalText.uasset new file mode 100644 index 0000000..1516e62 Binary files /dev/null and b/Content/UI/Components/UIC_JournalText.uasset differ diff --git a/Lost_Edge.uproject b/Lost_Edge.uproject index 4534c52..2b471ef 100644 --- a/Lost_Edge.uproject +++ b/Lost_Edge.uproject @@ -1,6 +1,6 @@ { "FileVersion": 3, - "EngineAssociation": "{42CC8720-4DDD-EF11-BECE-CEBF292119D8}", + "EngineAssociation": "5.4", "Category": "", "Description": "", "Modules": [ @@ -369,6 +369,14 @@ "Name": "FlatNodes", "Enabled": true, "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/b719437f3fb54c259b34227363df8cab" + }, + { + "Name": "VisualStudioTools", + "Enabled": true, + "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/362651520df94e4fa65492dbcba44ae2", + "SupportedTargetPlatforms": [ + "Win64" + ] } ], "TargetPlatforms": [ diff --git a/Source/Lost_Edge/Private/CutsceneManager.cpp b/Source/Lost_Edge/Private/CutsceneManager.cpp index 5007cac..179e568 100644 --- a/Source/Lost_Edge/Private/CutsceneManager.cpp +++ b/Source/Lost_Edge/Private/CutsceneManager.cpp @@ -28,12 +28,15 @@ UCutsceneManager::UCutsceneManager() } } -void UCutsceneManager::EnqueueSequence(ULevelSequence* sequence, FCutsceneEndCallback endCallback) +void UCutsceneManager::EnqueueSequence(TSoftObjectPtr sequence, FCutsceneEndCallback endCallback) { - if(!sequence) + if(!sequence.LoadSynchronous()) return; - if(_nextSequences.IsEmpty() && !_sequencePlayer) // most first sequence, so widgets and binds don't exist + FScopeLock lock1(&_sequencesLock); + FScopeLock lock2(&_callbacksLock); + + if(_endCallbacks.IsEmpty()) // most first sequence, so widgets and binds don't exist { if(auto PC = UGameplayStatics::GetPlayerController(GetWorld(), 0)) { @@ -53,7 +56,7 @@ void UCutsceneManager::EnqueueSequence(ULevelSequence* sequence, FCutsceneEndCal static FSkipCutsceneDelegate skipCutsceneDelegate; if(!skipCutsceneDelegate.IsBound()) skipCutsceneDelegate.BindDynamic(this, &UCutsceneManager::SkipSequence); - WM->EnableCutsceneWidget(mapping.Key.GetDisplayName(false), skipCutsceneDelegate); + WM->EnableCutsceneWidget(skipCutsceneDelegate); } } } @@ -75,9 +78,11 @@ void UCutsceneManager::PlayNextSequence() _sequencePlayer->MarkAsGarbage(); } - ULevelSequence* sequence; + FScopeLock lock(&_sequencesLock); + + TSoftObjectPtr sequence; _nextSequences.Dequeue(sequence); - _sequencePlayer = ULevelSequencePlayer::CreateLevelSequencePlayer(GetWorld(), sequence, FMovieSceneSequencePlaybackSettings{}, _sequencePlayerActor); + _sequencePlayer = ULevelSequencePlayer::CreateLevelSequencePlayer(GetWorld(), sequence.LoadSynchronous(), FMovieSceneSequencePlaybackSettings{}, _sequencePlayerActor); _sequencePlayer->OnStop.AddDynamic(this, &UCutsceneManager::OnSequenceEnd); _sequencePlayer->Play(); } @@ -93,6 +98,8 @@ void UCutsceneManager::SkipSequence() void UCutsceneManager::ClearQueue() { + FScopeLock lock1(&_sequencesLock); + FScopeLock lock2(&_callbacksLock); if(!_nextSequences.IsEmpty()) _nextSequences.Empty(); if(!_endCallbacks.IsEmpty()) @@ -112,6 +119,8 @@ void UCutsceneManager::OnSequenceEnd() _sequencePlayer->MarkAsGarbage(); _sequencePlayer = nullptr; + FScopeLock lock(&_callbacksLock); + FCutsceneEndCallback callback; _endCallbacks.Dequeue(callback); if(callback.IsBound()) diff --git a/Source/Lost_Edge/Private/CutsceneManager.h b/Source/Lost_Edge/Private/CutsceneManager.h index 49e6c68..fc21fde 100644 --- a/Source/Lost_Edge/Private/CutsceneManager.h +++ b/Source/Lost_Edge/Private/CutsceneManager.h @@ -17,12 +17,15 @@ public: UCutsceneManager(); UFUNCTION(BlueprintCallable) - void EnqueueSequence(class ULevelSequence* sequence, FCutsceneEndCallback endCallback); + void EnqueueSequence(TSoftObjectPtr sequence, FCutsceneEndCallback endCallback); UFUNCTION(BlueprintCallable) void SkipSequence(); + UFUNCTION(BlueprintCallable) void ClearQueue(); + + UFUNCTION(BlueprintCallable) void LockCallback(bool lock); private: @@ -35,8 +38,10 @@ private: class ULevelSequencePlayer* _sequencePlayer = nullptr; class ALevelSequenceActor* _sequencePlayerActor = nullptr; - TQueue _nextSequences; + TQueue> _nextSequences; + FCriticalSection _sequencesLock; TQueue _endCallbacks; + FCriticalSection _callbacksLock; class APlayerBase* _lastPlayer = nullptr; TSoftObjectPtr _inputContext; diff --git a/Source/Lost_Edge/Private/DialogueManager.cpp b/Source/Lost_Edge/Private/DialogueManager.cpp new file mode 100644 index 0000000..ec089a0 --- /dev/null +++ b/Source/Lost_Edge/Private/DialogueManager.cpp @@ -0,0 +1,262 @@ +// Oleg Petruny proprietary. + + +#include "DialogueManager.h" + +#include "Components/AudioComponent.h" +#include "Engine/DataTable.h" +#include "EnhancedInputComponent.h" +#include "InputMappingContext.h" +#include "Kismet/GameplayStatics.h" +#include "Kismet/KismetMathLibrary.h" +#include "Sound/SoundWave.h" + +#include "CustomGameInstanceBase.h" +#include "MainGameModeBase.h" +#include "PlayerBase.h" +#include "Widgets/DialogueSkipWidget.h" +#include "Widgets/InputAnimatedWidgetInterface.h" +#include "Widgets/WidgetsManager.h" + +UDialogueManager::UDialogueManager() +{ + _inputContext = { FSoftObjectPath{ TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/IMC_Dialogue.IMC_Dialogue'") } }; + if(auto world = GetWorld()) + { + if(auto GI = Cast(world->GetGameInstance())) + { + GI->inputContexts.Add(_inputContext); + } + } +} + +void UDialogueManager::PlayDialogue(FDialogueEnqueProperties properties, FDialogueEndCallback endCallback) +{ + if(!properties.dialogue) + return; + + if(properties.playMode == EDialoguePlayMode::Random) + { + TArray rows = properties.dialogue.LoadSynchronous()->GetRowNames(); + properties.rowName = rows[FMath::RandRange(0, rows.Num() - 1)]; + } + + FDialogueRow* row = reinterpret_cast(properties.dialogue.LoadSynchronous()->FindRowUnchecked(properties.rowName)); + + if(!row) + return; + + FTimerHandle timer; + int32 timerId; + _timersLock.Lock(); + timerId = _timers.Num(); + _timers.Add(timer); + _timersLock.Unlock(); + + UGameplayStatics::PlaySound2D(this, row->wave.LoadSynchronous()); + if(auto WM = AMainGameModeBase::GetWidgetsManager()) + { + WM->ShowDialogueWidget(*row); + } + + auto func = [properties = properties, + timerId = timerId, + _timersLock = &_timersLock, + _timers = &_timers, + endCallback = endCallback]() + { + FDialogueRow* row = reinterpret_cast(properties.dialogue.LoadSynchronous()->FindRowUnchecked(properties.rowName)); + if(auto WM = AMainGameModeBase::GetWidgetsManager()) + { + WM->HideDialogueWidget(*row); + } + + _timersLock->Lock(); + _timers->RemoveAt(timerId); + _timersLock->Unlock(); + + endCallback.Execute(); + }; + + float duration = row->wave ? row->wave->GetDuration() : row->duration; + GetWorld()->GetTimerManager().SetTimer(timer, func, duration, false); +} + +void UDialogueManager::EnqueDialogue(FDialogueEnqueProperties properties, FDialogueEndCallback endCallback) +{ + if(!properties.dialogue.LoadSynchronous()) + return; + + FScopeLock lock1(&_dialoguesLock); + FScopeLock lock2(&_callbacksLock); + + if(_endCallbacks.IsEmpty()) // most first dialogue, so widgets and binds don't exist + { + if(auto PC = UGameplayStatics::GetPlayerController(GetWorld(), 0)) + { + _lastPlayer = Cast(PC->GetPawn()); + if(_lastPlayer) + { + auto& mapping = _inputContext.LoadSynchronous()->GetMapping(0); + _inputHandler = _lastPlayer->inputComponent->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &UDialogueManager::OnInputPress).GetHandle(); + + if(auto WM = AMainGameModeBase::GetWidgetsManager()) + { + static FDialogueSkipDelegate skipDialogueDelegate; + if(!skipDialogueDelegate.IsBound()) + { + skipDialogueDelegate.BindDynamic(this, &UDialogueManager::SkipDialogue); + WM->SetInputDialogueWidget(mapping.Key, mapping.Action->ActionDescription, skipDialogueDelegate); + } + } + } + } + } + + _nextDialogues.Enqueue(properties); + _endCallbacks.Enqueue(endCallback); + + PlayNextDialogue(); +} + +void UDialogueManager::PlayNextDialogue() +{ + _dialoguesLock.Lock(); + + auto properties = _nextDialogues.Peek(); + + TArray rows = properties->dialogue.LoadSynchronous()->GetRowNames(); + if(rows.Num() == 0) + { + FDialogueEndCallback callback; + if(_endCallbacks.Dequeue(callback)) + callback.Execute(); + _nextDialogues.Pop(); + return; + } + + if(properties->playMode == EDialoguePlayMode::Random) + { + properties->rowName = rows[FMath::RandRange(0, rows.Num() - 1)]; + } + + FDialogueRow* row = reinterpret_cast(properties->dialogue.LoadSynchronous()->FindRowUnchecked(properties->rowName)); + + if(!row) + { + FDialogueEndCallback callback; + _endCallbacks.Dequeue(callback); + callback.Execute(); + _nextDialogues.Pop(); + return; + } + + if(properties->playMode == EDialoguePlayMode::Sequential) + { + if(!properties->rowName.ToString().IsNumeric()) + { + _nextDialogues.Pop(); + FDialogueEndCallback callback; + if(_endCallbacks.Dequeue(callback)) + callback.Execute(); + return; + } + } + + if(row->wave.LoadSynchronous()) + leadDialogueAudio = UGameplayStatics::SpawnSound2D(this, row->wave.LoadSynchronous()); + else + leadDialogueAudio = nullptr; + + if(auto WM = AMainGameModeBase::GetWidgetsManager()) + { + WM->ShowDialogueWidget(*row); + } + + FTimerHandle timer; + int32 timerId; + + const float duration = row->wave ? row->wave->GetDuration() : row->duration; + GetWorld()->GetTimerManager().SetTimer(timer, [&]() { OnDialogueEnd(); }, duration, false); + + _timersLock.Lock(); + timerId = _timers.Num(); + _timers.Add(timer); + _timersLock.Unlock(); + + leadDialogueTimerId = timerId; + leadDialogueProperties = properties; + + _dialoguesLock.Unlock(); +} + +void UDialogueManager::SkipDialogue() +{ + if(_timers.Num() == 0 || leadDialogueTimerId < 0) + return; + + _timersLock.Lock(); + GetWorld()->GetTimerManager().ClearTimer(_timers[leadDialogueTimerId]); + _timers.RemoveAt(leadDialogueTimerId); + leadDialogueTimerId = -1; + _timersLock.Unlock(); + + if(leadDialogueAudio) + leadDialogueAudio->Stop(); + + OnDialogueEnd(); +} + +void UDialogueManager::ClearQueue() +{ + if(!_nextDialogues.IsEmpty()) + _nextDialogues.Empty(); + if(!_endCallbacks.IsEmpty()) + _endCallbacks.Empty(); +} + +void UDialogueManager::LockCallback(bool lock) +{ + _lockCallback = lock; +} + +void UDialogueManager::OnDialogueEnd() +{ + _dialoguesLock.Lock(); + + FDialogueRow* row = reinterpret_cast(leadDialogueProperties->dialogue.LoadSynchronous()->FindRowUnchecked(leadDialogueProperties->rowName)); + + if(auto WM = AMainGameModeBase::GetWidgetsManager()) + { + WM->HideDialogueWidget(*row); + } + + if(leadDialogueProperties->playMode == EDialoguePlayMode::Sequential) + { + if(leadDialogueProperties->rowName.ToString().IsNumeric()) + { + leadDialogueProperties->rowName = FName(FString::FromInt(FCString::Atoi(*(leadDialogueProperties->rowName.ToString())) + 1)); + } + } + + _dialoguesLock.Unlock(); + + if(!_endCallbacks.IsEmpty()) + PlayNextDialogue(); + + _dialoguesLock.Lock(); + if(_endCallbacks.IsEmpty() && _lastPlayer) + { + _lastPlayer->inputComponent->RemoveBindingByHandle(_inputHandler); + _lastPlayer = nullptr; + } + _dialoguesLock.Unlock(); +} + +void UDialogueManager::OnInputPress() +{ + if(auto WM = AMainGameModeBase::GetWidgetsManager()) + { + WM->AnimateDialogueWidget(EInputAnimatedWidgetAnimation::Click); + } +} diff --git a/Source/Lost_Edge/Private/DialogueManager.h b/Source/Lost_Edge/Private/DialogueManager.h new file mode 100644 index 0000000..4b60ce2 --- /dev/null +++ b/Source/Lost_Edge/Private/DialogueManager.h @@ -0,0 +1,111 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "UObject/Object.h" + +#include "DialogueManager.generated.h" + +UENUM(BlueprintType) +enum class EDialogueWaveType : uint8 +{ + Main, + Secondary, + Sound +}; + +USTRUCT(BlueprintType) +struct FDialogueRow : public FTableRowBase +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + TSoftObjectPtr wave = nullptr; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + EDialogueWaveType type = EDialogueWaveType::Main; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float duration = 2.0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FString id = ""; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FText text = FText::GetEmpty(); +}; + +UENUM(BlueprintType) +enum class EDialoguePlayMode : uint8 +{ + Sequential, + ExactRow, + Random +}; + +USTRUCT(BlueprintType) +struct FDialogueEnqueProperties +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + TSoftObjectPtr dialogue = nullptr; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + EDialoguePlayMode playMode = EDialoguePlayMode::Sequential; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FName rowName = TEXT("1"); +}; + +DECLARE_DYNAMIC_DELEGATE(FDialogueEndCallback); + +UCLASS(BlueprintType) +class UDialogueManager : public UObject +{ + GENERATED_BODY() + +public: + UDialogueManager(); + + // Ignores play mode and force pushing dialogue + UFUNCTION(BlueprintCallable) + void PlayDialogue(FDialogueEnqueProperties properties, FDialogueEndCallback endCallback); + + UFUNCTION(BlueprintCallable) + void EnqueDialogue(FDialogueEnqueProperties properties, FDialogueEndCallback endCallback); + + UFUNCTION(BlueprintCallable) + void SkipDialogue(); + + UFUNCTION(BlueprintCallable) + void ClearQueue(); + + UFUNCTION(BlueprintCallable) + void LockCallback(bool lock); + +private: + void PlayNextDialogue(); + UFUNCTION() + void OnDialogueEnd(); + + void OnInputPress(); + + TQueue _nextDialogues; + FCriticalSection _dialoguesLock; + TQueue _endCallbacks; + FCriticalSection _callbacksLock; + + TArray _timers; + FCriticalSection _timersLock; + + int32 leadDialogueTimerId = -1; + FDialogueEnqueProperties* leadDialogueProperties; + class UAudioComponent* leadDialogueAudio; + + class APlayerBase* _lastPlayer = nullptr; + TSoftObjectPtr _inputContext; + int32 _inputHandler; + + bool _lockCallback = false; +}; diff --git a/Source/Lost_Edge/Private/Interactable/Interactable.h b/Source/Lost_Edge/Private/Interactable/Interactable.h index b5fe094..5513ce2 100644 --- a/Source/Lost_Edge/Private/Interactable/Interactable.h +++ b/Source/Lost_Edge/Private/Interactable/Interactable.h @@ -27,7 +27,7 @@ enum class EActivatorType : uint8 }; ENUM_CLASS_FLAGS(EActivatorType); -UCLASS(Abstract, MinimalAPI, Blueprintable, BlueprintType) +UCLASS(Blueprintable, BlueprintType, MinimalAPI) class AInteractable : public AActor { GENERATED_BODY() diff --git a/Source/Lost_Edge/Private/Levels/Level2.cpp b/Source/Lost_Edge/Private/Levels/Level2.cpp new file mode 100644 index 0000000..45bd80f --- /dev/null +++ b/Source/Lost_Edge/Private/Levels/Level2.cpp @@ -0,0 +1,22 @@ +// Oleg Petruny proprietary. + + +#include "Level2.h" + +#include "Atmosphere/AtmosphericFog.h" +#include "Components/LightComponent.h" +#include "Engine/DirectionalLight.h" +#include "Engine/SkyLight.h" +#include "LevelSequencePlayer.h" + +#include "CutsceneManager.h" +#include "MainGameModeBase.h" + +void ALevel2::BeginPlay() +{ + AMainGameModeBase::leadLevel = this; + + ALevelBase::BeginPlay(); + + CallNextState(); +} diff --git a/Source/Lost_Edge/Private/Levels/Level2.h b/Source/Lost_Edge/Private/Levels/Level2.h new file mode 100644 index 0000000..8c51010 --- /dev/null +++ b/Source/Lost_Edge/Private/Levels/Level2.h @@ -0,0 +1,17 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "LevelBase.h" + +#include "Level2.generated.h" + +UCLASS(BlueprintType) +class ALevel2 : public ALevelBase +{ + GENERATED_BODY() + +protected: + virtual void BeginPlay() override; + +}; diff --git a/Source/Lost_Edge/Private/Levels/Level3.cpp b/Source/Lost_Edge/Private/Levels/Level3.cpp new file mode 100644 index 0000000..de192b4 --- /dev/null +++ b/Source/Lost_Edge/Private/Levels/Level3.cpp @@ -0,0 +1,22 @@ +// Oleg Petruny proprietary. + + +#include "Level3.h" + +#include "Atmosphere/AtmosphericFog.h" +#include "Components/LightComponent.h" +#include "Engine/DirectionalLight.h" +#include "Engine/SkyLight.h" +#include "LevelSequencePlayer.h" + +#include "CutsceneManager.h" +#include "MainGameModeBase.h" + +void ALevel3::BeginPlay() +{ + AMainGameModeBase::leadLevel = this; + + ALevelBase::BeginPlay(); + + CallNextState(); +} diff --git a/Source/Lost_Edge/Private/Levels/Level3.h b/Source/Lost_Edge/Private/Levels/Level3.h new file mode 100644 index 0000000..57800a2 --- /dev/null +++ b/Source/Lost_Edge/Private/Levels/Level3.h @@ -0,0 +1,17 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "LevelBase.h" + +#include "Level3.generated.h" + +UCLASS(BlueprintType) +class ALevel3 : public ALevelBase +{ + GENERATED_BODY() + +protected: + virtual void BeginPlay() override; + +}; diff --git a/Source/Lost_Edge/Private/Levels/Level4.cpp b/Source/Lost_Edge/Private/Levels/Level4.cpp new file mode 100644 index 0000000..23192d8 --- /dev/null +++ b/Source/Lost_Edge/Private/Levels/Level4.cpp @@ -0,0 +1,22 @@ +// Oleg Petruny proprietary. + + +#include "Level4.h" + +#include "Atmosphere/AtmosphericFog.h" +#include "Components/LightComponent.h" +#include "Engine/DirectionalLight.h" +#include "Engine/SkyLight.h" +#include "LevelSequencePlayer.h" + +#include "CutsceneManager.h" +#include "MainGameModeBase.h" + +void ALevel4::BeginPlay() +{ + AMainGameModeBase::leadLevel = this; + + ALevelBase::BeginPlay(); + + CallNextState(); +} diff --git a/Source/Lost_Edge/Private/Levels/Level4.h b/Source/Lost_Edge/Private/Levels/Level4.h new file mode 100644 index 0000000..7096d4e --- /dev/null +++ b/Source/Lost_Edge/Private/Levels/Level4.h @@ -0,0 +1,17 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "LevelBase.h" + +#include "Level4.generated.h" + +UCLASS(BlueprintType) +class ALevel4 : public ALevelBase +{ + GENERATED_BODY() + +protected: + virtual void BeginPlay() override; + +}; diff --git a/Source/Lost_Edge/Private/Levels/Level5.cpp b/Source/Lost_Edge/Private/Levels/Level5.cpp new file mode 100644 index 0000000..cf03d92 --- /dev/null +++ b/Source/Lost_Edge/Private/Levels/Level5.cpp @@ -0,0 +1,22 @@ +// Oleg Petruny proprietary. + + +#include "Level5.h" + +#include "Atmosphere/AtmosphericFog.h" +#include "Components/LightComponent.h" +#include "Engine/DirectionalLight.h" +#include "Engine/SkyLight.h" +#include "LevelSequencePlayer.h" + +#include "CutsceneManager.h" +#include "MainGameModeBase.h" + +void ALevel5::BeginPlay() +{ + AMainGameModeBase::leadLevel = this; + + ALevelBase::BeginPlay(); + + CallNextState(); +} diff --git a/Source/Lost_Edge/Private/Levels/Level5.h b/Source/Lost_Edge/Private/Levels/Level5.h new file mode 100644 index 0000000..5485ebb --- /dev/null +++ b/Source/Lost_Edge/Private/Levels/Level5.h @@ -0,0 +1,17 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "LevelBase.h" + +#include "Level5.generated.h" + +UCLASS(BlueprintType) +class ALevel5 : public ALevelBase +{ + GENERATED_BODY() + +protected: + virtual void BeginPlay() override; + +}; diff --git a/Source/Lost_Edge/Private/MainGameModeBase.cpp b/Source/Lost_Edge/Private/MainGameModeBase.cpp index fd01f94..d8847a0 100644 --- a/Source/Lost_Edge/Private/MainGameModeBase.cpp +++ b/Source/Lost_Edge/Private/MainGameModeBase.cpp @@ -10,17 +10,23 @@ #include "CustomGameInstanceBase.h" #include "CutsceneManager.h" +#include "DialogueManager.h" #include "Levels/LevelBase.h" +#include "QuestManager.h" #include "Widgets/WidgetsManager.h" UWidgetsManager* AMainGameModeBase::_widgetsManager = nullptr; UCutsceneManager* AMainGameModeBase::_cutsceneManager = nullptr; +UDialogueManager* AMainGameModeBase::_dialogueManager = nullptr; +UQuestManager* AMainGameModeBase::_questManager = nullptr; ALevelBase* AMainGameModeBase::leadLevel = nullptr; void AMainGameModeBase::StartPlay() { _widgetsManager = NewObject(this, widgetManagerClass); _cutsceneManager = NewObject(this); + _dialogueManager = NewObject(this); + _questManager = NewObject(this); AGameModeBase::StartPlay(); @@ -59,6 +65,11 @@ UCutsceneManager* AMainGameModeBase::GetCutsceneManager() return _cutsceneManager; } +UDialogueManager* AMainGameModeBase::GetDialogueManager() +{ + return _dialogueManager; +} + void AMainGameModeBase::CallNextLevelState() { if(leadLevel) diff --git a/Source/Lost_Edge/Private/MainGameModeBase.h b/Source/Lost_Edge/Private/MainGameModeBase.h index ad59888..79d8097 100644 --- a/Source/Lost_Edge/Private/MainGameModeBase.h +++ b/Source/Lost_Edge/Private/MainGameModeBase.h @@ -2,11 +2,12 @@ #pragma once -#include "CoreMinimal.h" #include "GameFramework/GameModeBase.h" #include "MainGameModeBase.generated.h" +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FQuestsUpdateDelegate, TArray, quests); + UCLASS() class AMainGameModeBase : public AGameModeBase { @@ -17,18 +18,22 @@ public: virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; virtual bool SetPause(APlayerController* PC, FCanUnpause CanUnpauseDelegate = FCanUnpause()) override; - void SwitchCameraMode(); - UFUNCTION(BlueprintPure) static class UWidgetsManager* GetWidgetsManager(); UFUNCTION(BlueprintPure) static class UCutsceneManager* GetCutsceneManager(); + UFUNCTION(BlueprintPure) + static class UDialogueManager* GetDialogueManager(); UFUNCTION(BlueprintCallable) static void CallNextLevelState(); + void SwitchCameraMode(); + static class ALevelBase* leadLevel; + FQuestsUpdateDelegate questsUpdateDelegate; + protected: UPROPERTY(EditDefaultsOnly) TSubclassOf widgetManagerClass; @@ -36,4 +41,6 @@ protected: private: static class UWidgetsManager* _widgetsManager; static class UCutsceneManager* _cutsceneManager; + static class UDialogueManager* _dialogueManager; + static class UQuestManager* _questManager; }; diff --git a/Source/Lost_Edge/Private/PlayerBase.cpp b/Source/Lost_Edge/Private/PlayerBase.cpp index e97f21d..6aa0db5 100644 --- a/Source/Lost_Edge/Private/PlayerBase.cpp +++ b/Source/Lost_Edge/Private/PlayerBase.cpp @@ -330,3 +330,9 @@ void APlayerBase::ShowInventory() if(auto WM = AMainGameModeBase::GetWidgetsManager()) WM->ShowInventory(); } + +void APlayerBase::ShowJournal() +{ + if(auto WM = AMainGameModeBase::GetWidgetsManager()) + WM->ShowJournal(); +} diff --git a/Source/Lost_Edge/Private/PlayerBase.h b/Source/Lost_Edge/Private/PlayerBase.h index 4d46e87..013dc00 100644 --- a/Source/Lost_Edge/Private/PlayerBase.h +++ b/Source/Lost_Edge/Private/PlayerBase.h @@ -84,6 +84,9 @@ protected: UFUNCTION(BlueprintCallable, Category = Character) void ShowInventory(); + UFUNCTION(BlueprintCallable, Category = Character) + void ShowJournal(); + class APlayerController* playerController; UPROPERTY(EditAnywhere) float moveSpeed = 200; diff --git a/Source/Lost_Edge/Private/QuestManager.cpp b/Source/Lost_Edge/Private/QuestManager.cpp new file mode 100644 index 0000000..e02000e --- /dev/null +++ b/Source/Lost_Edge/Private/QuestManager.cpp @@ -0,0 +1,27 @@ +// Oleg Petruny proprietary. + + +#include "QuestManager.h" + +#include "Kismet/GameplayStatics.h" + +#include "Levels/LevelBase.h" +#include "MainGameModeBase.h" +#include "Widgets/WidgetsManager.h" + +UQuestManager::UQuestManager() +{ + if(auto gamemode_base = UGameplayStatics::GetGameMode(GetWorld())) + { + if(auto gamemode = Cast(gamemode_base)) + { + //gamemode->questsUpdateDelegate.AddDynamic(this, &UQuestManager::Update); + } + } +} + +void UQuestManager::Update(TArray quests) +{ + if(auto WM = AMainGameModeBase::GetWidgetsManager()) + WM->UpdateJournal(quests); +} diff --git a/Source/Lost_Edge/Private/QuestManager.h b/Source/Lost_Edge/Private/QuestManager.h new file mode 100644 index 0000000..005ec18 --- /dev/null +++ b/Source/Lost_Edge/Private/QuestManager.h @@ -0,0 +1,20 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "UObject/Object.h" + +#include "QuestManager.generated.h" + +UCLASS(BlueprintType) +class UQuestManager : public UObject +{ + GENERATED_BODY() + +public: + UQuestManager(); + +protected: + void Update(TArray quests); + +}; diff --git a/Source/Lost_Edge/Private/SaveManager.cpp b/Source/Lost_Edge/Private/SaveManager.cpp new file mode 100644 index 0000000..0e4aedc --- /dev/null +++ b/Source/Lost_Edge/Private/SaveManager.cpp @@ -0,0 +1,6 @@ +// Oleg Petruny proprietary. + + +#include "SaveManager.h" + + diff --git a/Source/Lost_Edge/Private/SaveManager.h b/Source/Lost_Edge/Private/SaveManager.h new file mode 100644 index 0000000..594ca6d --- /dev/null +++ b/Source/Lost_Edge/Private/SaveManager.h @@ -0,0 +1,19 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "UObject/Object.h" + +#include "SaveManager.generated.h" + +UCLASS(BlueprintType) +class USaveManager : public UObject +{ + GENERATED_BODY() + +public: + + +private: + +}; diff --git a/Source/Lost_Edge/Private/Widgets/InventoryWidget.cpp b/Source/Lost_Edge/Private/Widgets/AutohideWidget.cpp similarity index 64% rename from Source/Lost_Edge/Private/Widgets/InventoryWidget.cpp rename to Source/Lost_Edge/Private/Widgets/AutohideWidget.cpp index bcd9f97..9a9a46d 100644 --- a/Source/Lost_Edge/Private/Widgets/InventoryWidget.cpp +++ b/Source/Lost_Edge/Private/Widgets/AutohideWidget.cpp @@ -1,22 +1,22 @@ // Oleg Petruny proprietary. -#include "InventoryWidget.h" +#include "AutohideWidget.h" #include "Animation/WidgetAnimation.h" #include "Engine/World.h" #include "TimerManager.h" -void UInventoryWidget::Show() +void UAutohideWidget::Show() { SetVisibility(ESlateVisibility::Visible); if(!showTimer.IsValid()) PlayAnimation(showAnimation, GetAnimationCurrentTime(showAnimation), 1, EUMGSequencePlayMode::Forward, 1, false); - GetWorld()->GetTimerManager().SetTimer(showTimer, this, &UInventoryWidget::Hide, showDuration, false); + GetWorld()->GetTimerManager().SetTimer(showTimer, this, &UAutohideWidget::Hide, showDuration, false); } -void UInventoryWidget::Hide() +void UAutohideWidget::Hide() { + GetWorld()->GetTimerManager().ClearTimer(showTimer); PlayAnimation(showAnimation, GetAnimationCurrentTime(showAnimation), 1, EUMGSequencePlayMode::Reverse, 1, false); - showTimer.Invalidate(); -} +} \ No newline at end of file diff --git a/Source/Lost_Edge/Private/Widgets/AutohideWidget.h b/Source/Lost_Edge/Private/Widgets/AutohideWidget.h new file mode 100644 index 0000000..28597e2 --- /dev/null +++ b/Source/Lost_Edge/Private/Widgets/AutohideWidget.h @@ -0,0 +1,27 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "ResolutionResponsiveUserWidget.h" + +#include "AutohideWidget.generated.h" + +UCLASS() +class UAutohideWidget : public UResolutionResponsiveUserWidget +{ + GENERATED_BODY() + +public: + virtual void Show(); + + UPROPERTY(Transient, meta = (BindWidgetAnim)) + class UWidgetAnimation* showAnimation; + +protected: + virtual void Hide(); + + UPROPERTY(EditDefaultsOnly, meta = (ClampMin = "1.0")) + float showDuration = 2.0; + + FTimerHandle showTimer; +}; diff --git a/Source/Lost_Edge/Private/Widgets/DialogueRowWidget.h b/Source/Lost_Edge/Private/Widgets/DialogueRowWidget.h new file mode 100644 index 0000000..6241e72 --- /dev/null +++ b/Source/Lost_Edge/Private/Widgets/DialogueRowWidget.h @@ -0,0 +1,22 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "ResolutionResponsiveUserWidget.h" + +#include "DialogueRowWidget.generated.h" + +enum class EDialogueWaveType : uint8; + +UCLASS(Blueprintable, Abstract) +class UDialogueRowWidget : public UResolutionResponsiveUserWidget +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintImplementableEvent) + void SetStyle(EDialogueWaveType style); + + UPROPERTY(meta = (BindWidget)) + class UTextBlock* text; +}; diff --git a/Source/Lost_Edge/Private/Widgets/DialogueRowWidgetManager.cpp b/Source/Lost_Edge/Private/Widgets/DialogueRowWidgetManager.cpp new file mode 100644 index 0000000..244c9b4 --- /dev/null +++ b/Source/Lost_Edge/Private/Widgets/DialogueRowWidgetManager.cpp @@ -0,0 +1,83 @@ +// Oleg Petruny proprietary. + + +#include "DialogueRowWidgetManager.h" + +#include "Blueprint/WidgetTree.h" +#include "Components/TextBlock.h" +#include "Components/VerticalBox.h" + +#include "CommonFunctions.h" +#include "DialogueManager.h" +#include "Widgets/DialogueRowWidget.h" +#include "Widgets/DialogueSkipWidget.h" + +void UDialogueRowWidgetManager::SetInput(const FKey key, const FText desc, FDialogueSkipDelegate& delegate) +{ + dialogueSkipWidget->keyText->SetText(UCommonFunctions::GetKeyDisplayName(key)); + dialogueSkipWidget->descriptionText->SetText(desc); + dialogueSkipWidget->skipDialogueDelegate = delegate; +} + +void UDialogueRowWidgetManager::Append(const FDialogueRow& dialogue) +{ + FScopeLock Lock(&rowsLock); + + for(int32 i = rows->GetChildrenCount() - rowsIds.Num(); i < 1; ++i) + { + auto row = WidgetTree->ConstructWidget(rowWidgetClass); + row->SetVisibility(ESlateVisibility::Hidden); + rows->AddChild(row); + } + + auto row = Cast(rows->GetChildAt(rowsIds.Num())); + row->text->SetText(dialogue.text); + row->SetStyle(dialogue.type); + row->SetVisibility(ESlateVisibility::Visible); + + rowsIds.Add(dialogue.id); + + if(dialogue.type == EDialogueWaveType::Main) + { + if(count == 0) + dialogueSkipWidget->SetVisibility(ESlateVisibility::Visible); + ++count; + } +} + +void UDialogueRowWidgetManager::Remove(const struct FDialogueRow& dialogue) +{ + FScopeLock Lock(&rowsLock); + + if(dialogue.id == "") + { + for(int32 i = 0; i < rowsIds.Num(); ++i) + rows->GetChildAt(i)->SetVisibility(ESlateVisibility::Hidden); + rowsIds.Empty(); + + return; + } + + if(!rowsIds.Contains(dialogue.id)) + return; + + int32 index = rowsIds.Find(dialogue.id); + auto row = rows->GetChildAt(index); + row->SetVisibility(ESlateVisibility::Hidden); + rows->RemoveChildAt(index); + rows->AddChild(row); + + rowsIds.Remove(dialogue.id); + + if(dialogue.type == EDialogueWaveType::Main) + { + if(count == 1) + dialogueSkipWidget->SetVisibility(ESlateVisibility::Hidden); + --count; + } +} + +void UDialogueRowWidgetManager::AnimateSkipWidget(const EInputAnimatedWidgetAnimation animation) +{ + dialogueSkipWidget->RunAnimation(animation); +} diff --git a/Source/Lost_Edge/Private/Widgets/DialogueRowWidgetManager.h b/Source/Lost_Edge/Private/Widgets/DialogueRowWidgetManager.h new file mode 100644 index 0000000..11bcf0a --- /dev/null +++ b/Source/Lost_Edge/Private/Widgets/DialogueRowWidgetManager.h @@ -0,0 +1,35 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "Blueprint/UserWidget.h" + +#include "DialogueRowWidgetManager.generated.h" + +enum class EInputAnimatedWidgetAnimation : uint8; + +UCLASS(Blueprintable, Abstract) +class UDialogueRowWidgetManager : public UUserWidget +{ + GENERATED_BODY() + +public: + void SetInput(const FKey key, const FText desc, class FDialogueSkipDelegate& delegate); + void Append(const struct FDialogueRow& dialogue); + void Remove(const struct FDialogueRow& dialogue); + void AnimateSkipWidget(const EInputAnimatedWidgetAnimation animation); + +protected: + UPROPERTY(EditDefaultsOnly) + TSubclassOf rowWidgetClass; + + UPROPERTY(meta = (BindWidget)) + class UVerticalBox* rows; + + UPROPERTY(BlueprintReadWrite, meta = (BindWidget)) + class UDialogueSkipWidget* dialogueSkipWidget; + + TArray rowsIds; + FCriticalSection rowsLock; + int32 count = 0; +}; diff --git a/Source/Lost_Edge/Private/Widgets/DialogueSkipWidget.h b/Source/Lost_Edge/Private/Widgets/DialogueSkipWidget.h new file mode 100644 index 0000000..92e2deb --- /dev/null +++ b/Source/Lost_Edge/Private/Widgets/DialogueSkipWidget.h @@ -0,0 +1,29 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "InputAnimatedWidgetInterface.h" +#include "ResolutionResponsiveUserWidget.h" + +#include "DialogueSkipWidget.generated.h" + +DECLARE_DYNAMIC_DELEGATE(FDialogueSkipDelegate); + +UCLASS(Blueprintable, Abstract) +class UDialogueSkipWidget : public UResolutionResponsiveUserWidget, public IInputAnimatedWidgetInterface +{ + GENERATED_BODY() + +public: + FDialogueSkipDelegate skipDialogueDelegate; + + UPROPERTY(meta = (BindWidget)) + class UTextBlock* keyText; + UPROPERTY(meta = (BindWidget)) + class UTextBlock* descriptionText; + +protected: + UFUNCTION(BlueprintCallable) + void SkipDialogue() { skipDialogueDelegate.Execute(); } + +}; diff --git a/Source/Lost_Edge/Private/Widgets/InventoryWidget.h b/Source/Lost_Edge/Private/Widgets/InventoryWidget.h index 9caa053..7eb9ac0 100644 --- a/Source/Lost_Edge/Private/Widgets/InventoryWidget.h +++ b/Source/Lost_Edge/Private/Widgets/InventoryWidget.h @@ -2,19 +2,17 @@ #pragma once +#include "AutohideWidget.h" #include "InputAnimatedWidgetInterface.h" -#include "ResolutionResponsiveUserWidget.h" #include "InventoryWidget.generated.h" UCLASS(Blueprintable, Abstract) -class UInventoryWidget : public UResolutionResponsiveUserWidget, public IInputAnimatedWidgetInterface +class UInventoryWidget : public UAutohideWidget, public IInputAnimatedWidgetInterface { GENERATED_BODY() public: - void Show(); - UPROPERTY(meta = (BindWidget)) class UTextBlock* firstItemKeyText; UPROPERTY(meta = (BindWidget)) @@ -23,14 +21,4 @@ public: class UTextBlock* secondItemKeyText; UPROPERTY(meta = (BindWidget)) class UTextBlock* secondItemDescriptionText; - UPROPERTY(Transient, meta = (BindWidgetAnim)) - class UWidgetAnimation* showAnimation; - -protected: - void Hide(); - - UPROPERTY(EditDefaultsOnly, meta = (ClampMin = "1.0")) - float showDuration = 2.0; - - FTimerHandle showTimer; }; diff --git a/Source/Lost_Edge/Private/Widgets/JournalWidget.cpp b/Source/Lost_Edge/Private/Widgets/JournalWidget.cpp new file mode 100644 index 0000000..3c7ebcf --- /dev/null +++ b/Source/Lost_Edge/Private/Widgets/JournalWidget.cpp @@ -0,0 +1,20 @@ +// Oleg Petruny proprietary. + + +#include "JournalWidget.h" + +#include "Blueprint/WidgetTree.h" +#include "Components/TextBlock.h" +#include "Components/VerticalBox.h" + +void UJournalWidget::Update(TArray items) +{ + text->ClearChildren(); + for(auto& item : items) + { + auto obj = WidgetTree->ConstructWidget(textStyleClass); + obj->SetVisibility(ESlateVisibility::Visible); + obj->SetText(item); + text->AddChild(obj); + } +} diff --git a/Source/Lost_Edge/Private/Widgets/JournalWidget.h b/Source/Lost_Edge/Private/Widgets/JournalWidget.h new file mode 100644 index 0000000..089036d --- /dev/null +++ b/Source/Lost_Edge/Private/Widgets/JournalWidget.h @@ -0,0 +1,25 @@ +// Oleg Petruny proprietary. + +#pragma once + +#include "AutohideWidget.h" +#include "ResolutionResponsiveUserWidget.h" + +#include "JournalWidget.generated.h" + +UCLASS(Blueprintable, Abstract) +class UJournalWidget : public UAutohideWidget +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable) + void Update(TArray items); + + UPROPERTY(meta = (BindWidget)) + class UVerticalBox* text; + +protected: + UPROPERTY(EditDefaultsOnly) + TSubclassOf textStyleClass; +}; diff --git a/Source/Lost_Edge/Private/Widgets/WidgetsManager.cpp b/Source/Lost_Edge/Private/Widgets/WidgetsManager.cpp index eb2ed63..46310e2 100644 --- a/Source/Lost_Edge/Private/Widgets/WidgetsManager.cpp +++ b/Source/Lost_Edge/Private/Widgets/WidgetsManager.cpp @@ -14,10 +14,13 @@ #include "Interactable/Interactable.h" #include "Interactable/Modificators/InteractableModificator.h" #include "Interactable/Modificators/InventoryInteractableModificator.h" -#include "InteractableHintWidgetManager.h" #include "PlayerBase.h" #include "Widgets/CutsceneSkipWidget.h" +#include "Widgets/DialogueRowWidgetManager.h" +#include "Widgets/DialogueSkipWidget.h" +#include "Widgets/InteractableHintWidgetManager.h" #include "Widgets/InventoryWidget.h" +#include "Widgets/JournalWidget.h" void UWidgetsManager::Init() { @@ -50,6 +53,12 @@ void UWidgetsManager::Init() cutsceneSkipWidget->SetVisibility(ESlateVisibility::Hidden); cutsceneSkipWidget->AddToViewport(); } + if(auto instance = CreateWidget(PC, dialogueRowWidgetManagerClass)) + { + dialogueRowWidgetManager = instance; + dialogueRowWidgetManager->SetVisibility(ESlateVisibility::Visible); + dialogueRowWidgetManager->AddToViewport(); + } if(auto instance = CreateWidget(PC, inventoryWidgetClass)) { inventoryWidget = instance; @@ -69,9 +78,23 @@ void UWidgetsManager::Init() inventoryWidget->AddToViewport(); } + if(auto instance = CreateWidget(PC, journalWidgetClass)) + { + journalWidget = instance; + journalWidget->SetVisibility(ESlateVisibility::Hidden); + journalWidget->AddToViewport(); + } } } +void UWidgetsManager::UpdateInputKeys() +{ + // PLAYER CANT CHANGE UI KEYS FROM SETTINGS (maybe somewhere in future project) + + //cutsceneSkipWidget->keyText->SetText(keyText); + +} + void UWidgetsManager::HideWidgets() { for(auto& widget : overlayWidgetsInstances) @@ -81,6 +104,8 @@ void UWidgetsManager::HideWidgets() interactableHintWidgetManager->Remove(nullptr); if(inventoryWidget) inventoryWidget->SetVisibility(ESlateVisibility::Hidden); + if(journalWidget) + journalWidget->SetVisibility(ESlateVisibility::Hidden); } void UWidgetsManager::ShowWidgets() @@ -103,6 +128,8 @@ void UWidgetsManager::UpdateWidgetsOwner() } } + + void UWidgetsManager::ShowInteractionHints(const UInteractableModificator* modificator) { if(interactableHintWidgetManager) @@ -119,9 +146,10 @@ void UWidgetsManager::AnimateInteractionHint(const UInteractableModificator* mod interactableHintWidgetManager->AnimateInteractionHint(modificator, index, animation); } -void UWidgetsManager::EnableCutsceneWidget(FText keyText, FSkipCutsceneDelegate& skipCutsceneDelegate) + + +void UWidgetsManager::EnableCutsceneWidget(FSkipCutsceneDelegate& skipCutsceneDelegate) { - cutsceneSkipWidget->keyText->SetText(keyText); cutsceneSkipWidget->skipCutsceneDelegate = skipCutsceneDelegate; cutsceneSkipWidget->SetVisibility(ESlateVisibility::Visible); } @@ -134,24 +162,53 @@ void UWidgetsManager::AnimateCutsceneWidget(const EInputAnimatedWidgetAnimation cutsceneSkipWidget->RunAnimation(animation); } + + +void UWidgetsManager::SetInputDialogueWidget(const FKey key, const FText desc, FDialogueSkipDelegate& delegate) +{ + dialogueRowWidgetManager->SetInput(key, desc, delegate); +} + +void UWidgetsManager::ShowDialogueWidget(const FDialogueRow& dialogue) +{ + dialogueRowWidgetManager->Append(dialogue); +} +void UWidgetsManager::HideDialogueWidget(const FDialogueRow& dialogue) +{ + dialogueRowWidgetManager->Remove(dialogue); +} +void UWidgetsManager::AnimateDialogueWidget(const EInputAnimatedWidgetAnimation animation) +{ + dialogueRowWidgetManager->AnimateSkipWidget(animation); +} + + + void UWidgetsManager::ShowInventory() { inventoryWidget->Show(); } - void UWidgetsManager::ShowInventory(FText key1, FText key2) { inventoryWidget->firstItemKeyText->SetText(key2); inventoryWidget->secondItemKeyText->SetText(key1); ShowInventory(); } - void UWidgetsManager::SetInventoryFirstItem(FText item) { inventoryWidget->firstItemDescriptionText->SetText(item); } - void UWidgetsManager::SetInventorySecondItem(FText item) { inventoryWidget->secondItemDescriptionText->SetText(item); } + +void UWidgetsManager::ShowJournal() +{ + journalWidget->Show(); +} + +void UWidgetsManager::UpdateJournal(TArray text) +{ + journalWidget->Update(text); +} diff --git a/Source/Lost_Edge/Private/Widgets/WidgetsManager.h b/Source/Lost_Edge/Private/Widgets/WidgetsManager.h index b224148..a7265f0 100644 --- a/Source/Lost_Edge/Private/Widgets/WidgetsManager.h +++ b/Source/Lost_Edge/Private/Widgets/WidgetsManager.h @@ -15,6 +15,7 @@ class UWidgetsManager : public UObject public: void Init(); + void UpdateInputKeys(); void ShowWidgets(); void HideWidgets(); @@ -24,33 +25,49 @@ public: void HideInteractionHints(const class UInteractableModificator* modificator); void AnimateInteractionHint(const class UInteractableModificator* modificator, const int32 index, const EInputAnimatedWidgetAnimation animation); - void EnableCutsceneWidget(FText keyText, class FSkipCutsceneDelegate& skipCutsceneDelegate); + void EnableCutsceneWidget(class FSkipCutsceneDelegate& skipCutsceneDelegate); void DisableCutsceneWidget(); void AnimateCutsceneWidget(const EInputAnimatedWidgetAnimation animation); + void SetInputDialogueWidget(const FKey key, const FText desc, class FDialogueSkipDelegate& delegate); + void ShowDialogueWidget(const struct FDialogueRow& dialogue); + void HideDialogueWidget(const struct FDialogueRow& dialogue); + void AnimateDialogueWidget(const EInputAnimatedWidgetAnimation animation); + void ShowInventory(); void ShowInventory(FText key1, FText key2); void SetInventoryFirstItem(FText item); void SetInventorySecondItem(FText item); + void ShowJournal(); + void UpdateJournal(TArray text); + protected: UPROPERTY(EditDefaultsOnly) TSet> permaOverlayWidgets; // never hidden TArray permaOverlayWidgetsInstances; UPROPERTY(EditDefaultsOnly) - TSet> overlayWidgets; // hidden in pause + TSet> overlayWidgets; // hidden in pause, cutscene TArray overlayWidgetsInstances; UPROPERTY(EditDefaultsOnly) - TSubclassOf interactableHintWidgetManagerClass; + TSubclassOf interactableHintWidgetManagerClass; // hidden in cutscene class UInteractableHintWidgetManager* interactableHintWidgetManager = nullptr; UPROPERTY(EditDefaultsOnly) - TSubclassOf cutsceneSkipWidgetClass; + TSubclassOf cutsceneSkipWidgetClass; // never hidden class UCutsceneSkipWidget* cutsceneSkipWidget = nullptr; UPROPERTY(EditDefaultsOnly) - TSubclassOf inventoryWidgetClass; + TSubclassOf dialogueRowWidgetManagerClass; // hidden in cutscene + class UDialogueRowWidgetManager* dialogueRowWidgetManager = nullptr; + + UPROPERTY(EditDefaultsOnly) + TSubclassOf inventoryWidgetClass; // hidden in pause, cutscene class UInventoryWidget* inventoryWidget = nullptr; + + UPROPERTY(EditDefaultsOnly) + TSubclassOf journalWidgetClass; // hidden in pause, cutscene + class UJournalWidget* journalWidget = nullptr; };