From e6b7edcf8c3695875c64e1ad7b5a280704155154 Mon Sep 17 00:00:00 2001 From: PHILIP WHITE Date: Mon, 22 Jan 2024 23:04:39 +0000 Subject: [PATCH] Update Character Interact to Include Dialogue --- EndlessVendetta/.gitignore | 1 + .../Blueprints/BP_FirstPersonCharacter.uasset | 4 +- .../DialogueSystem/AC_Dialogue.h | 16 +++++ .../AC_PlayerDialogueInterpreter.cpp | 64 +++++++++++++------ .../AC_PlayerDialogueInterpreter.h | 8 ++- .../DialogueSystem/DialogueRootNode.cpp | 31 +++++++++ .../DialogueSystem/DialogueRootNode.h | 20 ++++++ .../DialogueSystem/DialogueTextNode.cpp | 1 - .../EndlessVendettaCharacter.cpp | 45 +++++++------ .../EndlessVendettaCharacter.h | 15 +++-- 10 files changed, 158 insertions(+), 47 deletions(-) create mode 100644 EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueRootNode.cpp create mode 100644 EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueRootNode.h diff --git a/EndlessVendetta/.gitignore b/EndlessVendetta/.gitignore index 24acec7a..54c50950 100644 --- a/EndlessVendetta/.gitignore +++ b/EndlessVendetta/.gitignore @@ -16,6 +16,7 @@ ### UnrealEngine ### # Visual Studio 2015 user specific files .vs/ +.idea/ # Compiled Object files *.slo diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset index ccadb20d..8aba01af 100644 --- a/EndlessVendetta/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ffeaf82a7decde92c259f80ff3253372f5659e0c4008a59b40b774fdc67fba50 -size 133260 +oid sha256:b50275292dee542bd0bb47e42fdc5d4d4b84ede65f96356b50ff0b8cc5c8def8 +size 173192 diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_Dialogue.h b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_Dialogue.h index 5d8635c0..80681856 100644 --- a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_Dialogue.h +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_Dialogue.h @@ -3,8 +3,12 @@ #pragma once #include "CoreMinimal.h" +#include "AC_PlayerDialogueInterpreter.h" #include "DialogueTree.h" #include "Components/ActorComponent.h" +#include "EndlessVendetta/EndlessVendettaCharacter.h" +#include "EndlessVendetta/InteractionInterface.h" +#include "Kismet/GameplayStatics.h" #include "AC_Dialogue.generated.h" @@ -14,6 +18,18 @@ class ENDLESSVENDETTA_API UAC_Dialogue : public UActorComponent GENERATED_BODY() public: + void Interact() const; + UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category = "Dialogue") UDialogueTree* DialogueTree; }; + +inline void UAC_Dialogue::Interact() const +{ + GLog->Log("Interacting with dialogue"); + if (!IsValid(DialogueTree)) return; + AEndlessVendettaCharacter* Character = Cast(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0)); + if (!IsValid(Cast(Character->GetComponentByClass(UAC_PlayerDialogueInterpreter::StaticClass())))) return; + Cast(Character->GetComponentByClass(UAC_PlayerDialogueInterpreter::StaticClass()))->StartDialogue(DialogueTree); + Character->bIsInDialogue = true; +} diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_PlayerDialogueInterpreter.cpp b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_PlayerDialogueInterpreter.cpp index 72be7b3a..f87077dc 100644 --- a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_PlayerDialogueInterpreter.cpp +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_PlayerDialogueInterpreter.cpp @@ -3,6 +3,8 @@ #include "AC_PlayerDialogueInterpreter.h" +#include "EndlessVendetta/EndlessVendettaCharacter.h" + // Sets default values for this component's properties UAC_PlayerDialogueInterpreter::UAC_PlayerDialogueInterpreter() @@ -37,39 +39,65 @@ void UAC_PlayerDialogueInterpreter::StartDialogue(UDialogueTree* DialogueTree) CurrentDialogueTree = DialogueTree; CurrentTextNode = Cast(DialogueTree->RootNodes[0]->ChildrenNodes[0]); OnStartDialogue.Broadcast(CurrentTextNode); + + if (APlayerController* PlayerController = GetWorld()->GetFirstPlayerController()) + { + FInputModeUIOnly InputModeData; + InputModeData.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock); + PlayerController->SetInputMode(InputModeData); + PlayerController->bShowMouseCursor = true; + } } void UAC_PlayerDialogueInterpreter::NextDialogue() { - if (IsValid(CurrentTextNode)) + if (!IsValid(CurrentTextNode)) return; + if (CurrentTextNode->ChildrenNodes.Num() == 0) { - if (Cast(CurrentTextNode->ChildrenNodes[0])) - { - CurrentTextNode = nullptr; - CurrentChoiceNode = Cast(CurrentTextNode->ChildrenNodes[0]); - OnChoiceDialogue.Broadcast(CurrentChoiceNode); - } - else - { - CurrentChoiceNode = nullptr; - CurrentTextNode = Cast(CurrentTextNode->ChildrenNodes[0]); - OnNextDialogue.Broadcast(CurrentTextNode); - } + EndDialogue(); + return; + } + if (Cast(CurrentTextNode->ChildrenNodes[0])) + { + CurrentChoiceNode = Cast(CurrentTextNode->ChildrenNodes[0]); + OnChoiceDialogue.Broadcast(CurrentChoiceNode); + CurrentTextNode = nullptr; + } + else + { + CurrentTextNode = Cast(CurrentTextNode->ChildrenNodes[0]); + OnNextDialogue.Broadcast(CurrentTextNode); + CurrentChoiceNode = nullptr; } } void UAC_PlayerDialogueInterpreter::MakeChoiceDialogue(const int Choice) { - if (Cast(CurrentTextNode->ChildrenNodes[Choice])) + if (!IsValid(CurrentChoiceNode)) return; + if (Cast(CurrentChoiceNode->ChildrenNodes[Choice])) { - CurrentTextNode = nullptr; - CurrentChoiceNode = Cast(CurrentTextNode->ChildrenNodes[Choice]); + CurrentChoiceNode = Cast(CurrentChoiceNode->ChildrenNodes[Choice]); OnChoiceDialogue.Broadcast(CurrentChoiceNode); + CurrentTextNode = nullptr; } else { - CurrentChoiceNode = nullptr; - CurrentTextNode = Cast(CurrentTextNode->ChildrenNodes[Choice]); + CurrentTextNode = Cast(CurrentChoiceNode->ChildrenNodes[Choice]); OnNextDialogue.Broadcast(CurrentTextNode); + CurrentChoiceNode = nullptr; + } +} + +void UAC_PlayerDialogueInterpreter::EndDialogue() +{ + CurrentChoiceNode = nullptr; + CurrentTextNode = nullptr; + OnEndDialogue.Broadcast(); + + if (APlayerController* PlayerController = GetWorld()->GetFirstPlayerController()) + { + const FInputModeGameAndUI InputModeData; + PlayerController->SetInputMode(InputModeData); + PlayerController->bShowMouseCursor = false; } } diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_PlayerDialogueInterpreter.h b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_PlayerDialogueInterpreter.h index 3f449ced..31da0195 100644 --- a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_PlayerDialogueInterpreter.h +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_PlayerDialogueInterpreter.h @@ -24,14 +24,18 @@ public: DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnChoiceDialogue, UDialogueChoiceNode*, ChoiceNode); + DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnEndDialogue); + UPROPERTY(BlueprintAssignable, Category = "Dialogue") FOnStartDialogue OnStartDialogue; UPROPERTY(BlueprintAssignable, Category = "Dialogue") FOnNextDialogue OnNextDialogue; UPROPERTY(BlueprintAssignable, Category = "Dialogue") FOnChoiceDialogue OnChoiceDialogue; + UPROPERTY(BlueprintAssignable, Category = "Dialogue") + FOnEndDialogue OnEndDialogue; - UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category = "Dialogue") + UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Dialogue") UDialogueTree* CurrentDialogueTree; protected: @@ -54,4 +58,6 @@ public: void NextDialogue(); UFUNCTION(BlueprintCallable, Category = "Dialogue") void MakeChoiceDialogue(int Choice); + UFUNCTION(BlueprintCallable, Category = "Dialogue") + void EndDialogue(); }; diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueRootNode.cpp b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueRootNode.cpp new file mode 100644 index 00000000..43a8ab4b --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueRootNode.cpp @@ -0,0 +1,31 @@ +#include "DialogueRootNode.h" +#include "DialogueTree.h" + +#define LOCTEXT_NAMESPACE "UDialogueChoiceNode" + +UDialogueRootNode::UDialogueRootNode() +{ +#if WITH_EDITORONLY_DATA + CompatibleGraphType = UDialogueTree::StaticClass(); + + ContextMenuName = LOCTEXT("ConextMenuName", "Root Node"); +#endif +} + +#if WITH_EDITOR +FText UDialogueRootNode::GetNodeTitle() const +{ + return LOCTEXT("Root Node", "ROOT"); +} + +FLinearColor UDialogueRootNode::GetBackgroundColor() const +{ + if (const UDialogueTree* DialogueTree = Cast(GetGraph()); DialogueTree == nullptr) + return Super::GetBackgroundColor(); + + return FLinearColor(1.f, 1.f, 1.f, 1.f); +} + +#endif + +#undef LOCTEXT_NAMESPACE diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueRootNode.h b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueRootNode.h new file mode 100644 index 00000000..38e6f2c0 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueRootNode.h @@ -0,0 +1,20 @@ +#pragma once + +#include "CoreMinimal.h" +#include "GenericGraphNode.h" +#include "DialogueRootNode.generated.h" + +UCLASS(Blueprintable) +class UDialogueRootNode : public UGenericGraphNode +{ + GENERATED_BODY() + +public: + UDialogueRootNode();; + +#if WITH_EDITOR + virtual FText GetNodeTitle() const override; + + virtual FLinearColor GetBackgroundColor() const override; +#endif +}; diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.cpp b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.cpp index 6d3e3c88..bc9c2e95 100644 --- a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.cpp +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.cpp @@ -37,7 +37,6 @@ FText UDialogueTextNode::GetNodeTitle() const } } } - UE_LOG(LogTemp, Warning, TEXT("Wrapped Text: %s"), *WrappedText); return FText::FromString(WrappedText); } diff --git a/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.cpp b/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.cpp index c2c87400..807aa0b4 100644 --- a/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.cpp +++ b/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.cpp @@ -14,6 +14,7 @@ #include "GameFramework/MovementComponent.h" #include "Inventory/InventoryComponent.h" #include "EndlessVendettaGameMode.h" +#include "DialogueSystem/AC_Dialogue.h" ////////////////////////////////////////////////////////////////////////// @@ -102,7 +103,7 @@ void AEndlessVendettaCharacter::Tick(float DeltaTime) } if (bPressedJump) { - if(CurrentStamina <= 0.0f) + if (CurrentStamina <= 0.0f) { CurrentStamina -= 20.0f; } @@ -123,7 +124,7 @@ void AEndlessVendettaCharacter::Tick(float DeltaTime) } if (!bIsPlayerSprinting) { - if(CurrentStamina >= 100.0f) + if (CurrentStamina >= 100.0f) { CurrentStamina = 100.0f; return; @@ -174,7 +175,7 @@ void AEndlessVendettaCharacter::SetupPlayerInputComponent(class UInputComponent* //Jumping EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Started, this, &ACharacter::Jump); EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping); - + //Moving EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AEndlessVendettaCharacter::Move); EnhancedInputComponent->BindAction(SprintAction, ETriggerEvent::Started, this, &AEndlessVendettaCharacter::Sprint); @@ -211,6 +212,11 @@ void AEndlessVendettaCharacter::SetupPlayerInputComponent(class UInputComponent* void AEndlessVendettaCharacter::Interact() { + if (bIsInDialogue) + { + Cast(GetComponentByClass(UAC_PlayerDialogueInterpreter::StaticClass()))->NextDialogue(); + return; + } if (PlayerOnShip) { SpaceShip->PlayerInteracting(); @@ -234,6 +240,10 @@ void AEndlessVendettaCharacter::Interact() UE_LOG(LogTemp, Warning, TEXT("Hit actor: %s"), *HitActor->GetName()); IInteractionInterface* InteractableActor = Cast(HitActor); if (InteractableActor) InteractableActor->Interact(); + if (UAC_Dialogue* Dialogue = Cast(HitActor->GetComponentByClass(UAC_Dialogue::StaticClass()))) + { + Dialogue->Interact(); + } } @@ -341,7 +351,7 @@ void AEndlessVendettaCharacter::EquipPrimary() if (IsValid(PrimaryWeapon)) { PrimaryWeapon->DetachFromActor(DetatchRules); - PrimaryWeapon->SetActorLocation(FVector(0,0,0), false, nullptr, ETeleportType::None); + PrimaryWeapon->SetActorLocation(FVector(0, 0, 0), false, nullptr, ETeleportType::None); PrimaryWeapon->SetActorHiddenInGame(true); this->GetFirstPersonCameraComponent()->SetFieldOfView(90); UE_LOG(LogTemp, Warning, TEXT("Primary Weapon Is Hidden: %hhd"), PrimaryWeapon->IsHidden()); @@ -351,7 +361,7 @@ void AEndlessVendettaCharacter::EquipPrimary() Cast(GetWorld()->GetAuthGameMode())->SendEvent("DeEquip", "Pri"); return; } - if(bIsWeaponPickedUp) + if (bIsWeaponPickedUp) { PrimaryWeaponActor = GetWorld()->SpawnActor(PrimaryWeaponClass, spawnParams); bIsWeaponPickedUp = false; @@ -390,12 +400,12 @@ void AEndlessVendettaCharacter::EquipSecondary() spawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; FAttachmentTransformRules AttachmentRules(EAttachmentRule::SnapToTarget, true); FDetachmentTransformRules DetatchRules(EDetachmentRule::KeepWorld, false); - + if (bIsReloading) return; if (IsValid(SecondaryWeapon)) { SecondaryWeapon->DetachFromActor(DetatchRules); - SecondaryWeapon->SetActorLocation(FVector(0,0,0), false, nullptr, ETeleportType::None); + SecondaryWeapon->SetActorLocation(FVector(0, 0, 0), false, nullptr, ETeleportType::None); SecondaryWeapon->SetActorHiddenInGame(true); this->GetFirstPersonCameraComponent()->SetFieldOfView(90); UE_LOG(LogTemp, Warning, TEXT("Secondary Weapon Is Hidden: %hhd"), SecondaryWeapon->IsHidden()); @@ -404,8 +414,8 @@ void AEndlessVendettaCharacter::EquipSecondary() GLog->Log("Secondary Weapon Put Away"); return; } - - if(bIsWeaponPickedUp) + + if (bIsWeaponPickedUp) { PrimaryWeaponActor = GetWorld()->SpawnActor(PrimaryWeaponClass, spawnParams); bIsWeaponPickedUp = false; @@ -415,11 +425,11 @@ void AEndlessVendettaCharacter::EquipSecondary() if (GadgetManager->IsValidReconGadget() && GadgetManager->IsReconEquipped() && !GadgetManager->TryToUnequipRecon()) return; if (GadgetManager->IsValidCombatGadget() && GadgetManager->IsCombatEquipped() && !GadgetManager->TryToUnequipCombat()) return; - - if(!IsValid(SecondaryWeapon)) + + if (!IsValid(SecondaryWeapon)) { bHasRifle = true; - if(!bIsSecondaryWeaponCreated) + if (!bIsSecondaryWeaponCreated) { SecondaryWeaponActor = GetWorld()->SpawnActor(SecondaryWeaponClass, spawnParams); SecondaryWeaponActor->AttachToComponent(Mesh1P, AttachmentRules, FName("GripPoint")); @@ -438,7 +448,7 @@ void AEndlessVendettaCharacter::EquipSecondary() void AEndlessVendettaCharacter::WeaponSwitcher(AActor* Outhit) { - if(Outhit->ActorHasTag("PrimaryWeapon")) + if (Outhit->ActorHasTag("PrimaryWeapon")) { if (IsValid(PrimaryWeapon)) { @@ -449,7 +459,7 @@ void AEndlessVendettaCharacter::WeaponSwitcher(AActor* Outhit) Outhit->Destroy(); EquipPrimary(); } - if(Outhit->ActorHasTag("SecondaryWeapon")) + if (Outhit->ActorHasTag("SecondaryWeapon")) { if (IsValid(SecondaryWeapon)) { @@ -565,7 +575,7 @@ void AEndlessVendettaCharacter::Move(const FInputActionValue& Value) SpaceShip->MoveShip(MovementVector); return; } - + if (Controller != nullptr) { // add movement @@ -669,7 +679,7 @@ void AEndlessVendettaCharacter::UpdateInventorySize(int Cols, int Rows) { Inventory->UpdateInventorySize(Cols, Rows); } - else + else { UE_LOG(LogTemp, Warning, TEXT("No Vaild Inventory")); } @@ -690,6 +700,5 @@ void AEndlessVendettaCharacter::ExitShip(FTransform ExitLoc) SetActorLocation(ExitLoc.GetLocation()); GetController()->SetControlRotation(ExitLoc.Rotator()); SpaceShip->Destroy(); - PlayerOnShip = false; + PlayerOnShip = false; } - diff --git a/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.h b/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.h index ca279fa5..1afe5a32 100644 --- a/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.h +++ b/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.h @@ -26,12 +26,12 @@ UCLASS(config=Game) class AEndlessVendettaCharacter : public ACharacter { GENERATED_BODY() - + protected: /** Pawn mesh: 1st person view (arms; seen only by self) */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Mesh) USkeletalMeshComponent* Mesh1P; - + private: /** First person camera */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true")) @@ -95,7 +95,7 @@ public: //STAMINA AND SPRINT SPEED UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Stats") - float MaxStamina = 100; + float MaxStamina = 100; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Stats") float CurrentStamina; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Stats") @@ -118,6 +118,9 @@ public: bool bIsSecondaryWeaponCreated = false; bool bIsWeaponPickedUp = false; + UPROPERTY(BlueprintReadWrite) + bool bIsInDialogue = false; + protected: virtual void BeginPlay() override; virtual void Tick(float DeltaTime) override; @@ -217,7 +220,6 @@ protected: void Interact(); protected: - // Used by vault it plugin to run vaulting animations USkeletalMeshComponent* FP_SkeletalMesh = nullptr; @@ -226,8 +228,6 @@ protected: // End of APawn interface public: - - UFUNCTION(BlueprintCallable, Category = "Stealth") void SetCrouch(); UFUNCTION(BlueprintCallable, Category = "Stealth") @@ -264,7 +264,8 @@ private: UPROPERTY(EditDefaultsOnly, Category = "Space Ship") TSubclassOf SpaceShipClass; ASpaceShip* SpaceShip; -public: + +public: void ExitShip(FTransform ExitLoc); void EnterShip(FTransform TakeoffLoc); };