// Fill out your copyright notice in the Description page of Project Settings. #include "TempCharacter.h" #include "Blueprint/UserWidget.h" #include "the_twilight_abyss/BaseItems/InventoryComponent.h" #include "the_twilight_abyss/BaseItems/Items/BaseItem.h" #include "GameFramework/CharacterMovementComponent.h" #include "the_twilight_abyss/MerchantInteraction/Interaction.h" #include #include "Components/PawnNoiseEmitterComponent.h" #include "Components/SphereComponent.h" #include "Kismet/KismetMathLibrary.h" // CONSTRUCTOR ATempCharacter::ATempCharacter() { // Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; Inventory = CreateDefaultSubobject("Inventory"); Inventory->MaxItemSlots = 10; this->GetCharacterMovement()->GetNavAgentPropertiesRef().bCanCrouch = true; } // Called when the game starts or when spawned void ATempCharacter::BeginPlay() { Super::BeginPlay(); Health = 100; ThisCamera = Cast(this->FindComponentByClass()); PlayerCapsule = GetCapsuleComponent(); TArray AllActorsInScene; //MAKE SURE POST PROCESSING IS IN THE SCENE OR GAME WILL CRASH UGameplayStatics::GetAllActorsOfClass(GetWorld(), APostProcessVolume::StaticClass(), AllActorsInScene); if (ensureMsgf(AllActorsInScene.Num() > 0, TEXT("No Post Processing Volume in scene"))) { PostProcessVolume = Cast(AllActorsInScene[0]); } Enemy = TEXT("Enemy"); //UGameplayStatics::GetAllActorsWithTag(GetWorld(), Enemy, AIActors); Ammo = TEXT("Ammo"); NoiseEmitter = Cast(this->FindComponentByClass(UPawnNoiseEmitterComponent::StaticClass())); //Widget Refs CrossHairWidget = CreateWidget(GetWorld(), CrossHairSub); CrossHairWidget->SetVisibility(ESlateVisibility::Visible); CrossHairWidget->AddToViewport(); ImportantStatsWidget = CreateWidget(GetWorld(), ImportantStatsSub); ImportantStatsWidget->SetVisibility(ESlateVisibility::Visible); ImportantStatsWidget->AddToViewport(); MainMenuWidget = CreateWidget(GetWorld(), MainMenuSub); MainMenuWidget->SetVisibility(ESlateVisibility::Hidden); MainMenuWidget->AddToViewport(); } //Binds the input we made in the setup player component to the forward vector void ATempCharacter::ForwardInput(float Axis) { AddMovementInput(UKismetMathLibrary::GetForwardVector(FRotator(0, GetControlRotation().Yaw, 0)) * Axis); if (isInStealth == false) MakeNoise(1.0f, this, GetActorLocation(), 1200.0f); } //Binds the input we made in the setup player component to the right vector void ATempCharacter::RightMoveInput(float Axis) { AddMovementInput(UKismetMathLibrary::GetRightVector(FRotator(0, GetControlRotation().Yaw, 0)) * Axis); if (isInStealth == false) MakeNoise(1.0f, this, GetActorLocation(), 1200.0f); } void ATempCharacter::Sneak() { UE_LOG(LogTemp, Display, TEXT("Sneak activated")); if (bIsCrouched) { UnCrouch(); isInStealth = false; if (PostProcessVolume != nullptr) PostProcessVolume->Settings.VignetteIntensity = 0.0f; //for (AActor* Actor : AIActors) //{ // USphereComponent* SphereComponent = Actor->FindComponentByClass(); // if (IsValid(SphereComponent)) // { // SphereComponent->SetSphereRadius(40.0f); //default value // } //} } else { Crouch(); isInStealth = true; /*for (AActor* Actor : AIActors) { USphereComponent* SphereComponent = Actor->FindComponentByClass(); if (IsValid(SphereComponent)) { SphereComponent->SetSphereRadius(5.0f); } }*/ if (PostProcessVolume != nullptr) PostProcessVolume->Settings.VignetteIntensity = 0.8f; } } // Called every frame void ATempCharacter::Tick(float DeltaTime) { Super::Tick(DeltaTime); } // Gives the character the functionality void ATempCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { Super::SetupPlayerInputComponent(PlayerInputComponent); PlayerInputComponent->BindAxis(TEXT("Move Forward / Backward"), this, &ATempCharacter::ForwardInput); PlayerInputComponent->BindAxis(TEXT("Move Right / Left"), this, &ATempCharacter::RightMoveInput); PlayerInputComponent->BindAxis(TEXT("Turn Right / Left Mouse"), this, &ATempCharacter::AddControllerYawInput); PlayerInputComponent->BindAxis(TEXT("Look Up / Down Mouse"), this, &ATempCharacter::AddControllerPitchInput); PlayerInputComponent->BindAction(TEXT("Jump"), IE_Pressed, this, &ATempCharacter::Jump); PlayerInputComponent->BindAction(TEXT("Sneak"), IE_Pressed, this, &ATempCharacter::Sneak); PlayerInputComponent->BindAction(TEXT("Sneak"), IE_Released, this, &ATempCharacter::Sneak); PlayerInputComponent->BindAction("Interact", IE_Pressed, this, &ATempCharacter::KeyPressed); } // When the player presses the E key void ATempCharacter::KeyPressed() { LineTraceLogic(); } // Line trace logic void ATempCharacter::LineTraceLogic() { //UE_LOG(LogTemp, Display, TEXT("LineTraceLogic activated")); float GlobalTrace = TraceDistance; FHitResult OutHit; ThisCamera = Cast(this->FindComponentByClass()); FVector Start = ThisCamera->GetComponentLocation(); FVector End = Start + GlobalTrace * ThisCamera->GetForwardVector(); FCollisionQueryParams TraceParams; TraceParams.AddIgnoredActor(this); bHit = GetWorld()->LineTraceSingleByChannel(OutHit, Start, End, ECC_Visibility, TraceParams); if (bHit) { //we store the GetItem function from InventoryComponent into ItemArray variable if (OutHit.GetActor() == nullptr) { return; } if (OutHit.GetActor()->FindComponentByClass()) { UE_LOG(LogTemp, Display, TEXT("Hit Merchant")); auto ItemArray = OutHit.GetActor()->FindComponentByClass()->GetItem(0); if (GoldBalance >= ItemArray->ItemCostPrice) { GoldBalance -= ItemArray->ItemCostPrice; Inventory->AddItem(ItemArray); UE_LOG(LogTemp, Display, TEXT("Item Purchased")); } if (GoldBalance <= 0) { UE_LOG(LogTemp, Display, TEXT("Not Enough Gold")); } if (OutHit.GetActor()->ActorHasTag(Ammo)) { OutHit.GetActor()->Destroy(); } } // if the actor hit has the interaction component/script then it will activate the code if (AInteraction* MyInteractable = Cast(OutHit.GetActor())) { if (MyInteractable->ShopDialogWidget->IsVisible()) { UE_LOG(LogTemp, Display, TEXT("ShopKeeper text is visible")); bShopKeeperText = true; return; } //if there is no text on screen this triggers else { if (MyInteractable->ItemSelectorWidget->IsVisible()) { return; } else { DrawDebugLine(GetWorld(), Start, End, FColor::Green, false, 1.0f); MyInteractable->OnInteract(); UE_LOG(LogTemp, Display, TEXT("OnInteract activated")); UE_LOG(LogTemp, Display, TEXT("HIT: %s"), *OutHit.GetActor()->GetName()); // While loop to check bisDisabled var until it changes to true while (MyInteractable->bisDisabled == false || MyInteractable->bDisableShopDialMove == false) { if (MyInteractable->bisDisabled == true || MyInteractable->bDisableShopDialMove == true) { InputDisabler(); break; } } } } } } } void ATempCharacter::InputDisabler() { //Disable Character Movement if (ACharacter* PlayerCharacter = Cast(GetWorld()->GetFirstPlayerController()->GetPawn())) { PlayerCharacter->DisableInput(GetWorld()->GetFirstPlayerController()); } //TURNING OFF CROSSHAIR & IMPORTANT STATS CrossHairWidget->SetVisibility(ESlateVisibility::Hidden); ImportantStatsWidget->SetVisibility(ESlateVisibility::Hidden); //Set to UI Mode Only APlayerController* PlayerController = GetWorld()->GetFirstPlayerController(); PlayerController->SetInputMode(FInputModeUIOnly()); PlayerController->bShowMouseCursor = true; disableTab = true; if (ThisCamera != nullptr) { return; } else { OriginalCameraFOV = ThisCamera->FieldOfView; } } void ATempCharacter::InputEnabler() { //Enable Character Movement if (ACharacter* PlayerCharacter = Cast(GetWorld()->GetFirstPlayerController()->GetPawn())) { PlayerCharacter->EnableInput(GetWorld()->GetFirstPlayerController()); } //TURNING ON THE CROSSHAIR AND IMPORTANTSTATS WIDGET CrossHairWidget->SetVisibility(ESlateVisibility::Visible); ImportantStatsWidget->SetVisibility(ESlateVisibility::Visible); //Reset UI Mode APlayerController* PlayerController = GetWorld()->GetFirstPlayerController(); PlayerController->SetInputMode(FInputModeGameOnly()); PlayerController->bShowMouseCursor = false; disableTab = true; TraceDistance = 300; if (ThisCamera != nullptr) { return; } else { ThisCamera->FieldOfView = OriginalCameraFOV; ThisCamera->ResetRelativeTransform(); } } void ATempCharacter::UseItem(class UBaseItem* Item) { if (Item) { Item->Use(this); Item->OnUse(this); //OnUse is a Blueprint Version } } void ATempCharacter::BuyItem() { UE_LOG(LogTemp, Display, TEXT("BUY ITEM FIRING")); TraceDistance = 1000; LineTraceLogic(); }