// 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/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; GoldBalance = GoldBalance; Health = Health; 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); PostProcessVolume = Cast(AllActorsInScene[0]); Enemy = TEXT("Enemy"); UGameplayStatics::GetAllActorsWithTag(GetWorld(), Enemy, AIActors); Ammo = TEXT("Ammo"); } //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); } //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); } void ATempCharacter::Sneak() { UE_LOG(LogTemp, Display, TEXT("Sneak activated")); if (bIsCrouched) { UnCrouch(); PostProcessVolume->Settings.VignetteIntensity = 0.0f; for (AActor* Actor : AIActors) { USphereComponent* SphereComponent = Actor->FindComponentByClass(); if (SphereComponent != nullptr) { SphereComponent->SetSphereRadius(40.0f); //default value } } } else { Crouch(); for (AActor* Actor : AIActors) { USphereComponent* SphereComponent = Actor->FindComponentByClass(); if (SphereComponent != nullptr) { SphereComponent->SetSphereRadius(15.0f); } } 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()); } //Set to UI Mode Only APlayerController* PlayerController = GetWorld()->GetFirstPlayerController(); PlayerController->SetInputMode(FInputModeUIOnly()); PlayerController->bShowMouseCursor = true; disableTab = true; if (ThisCamera != nullptr) { OriginalCameraLocation = ThisCamera->GetComponentLocation(); OriginalCameraRotation = ThisCamera->GetComponentRotation(); OriginalCameraFOV = ThisCamera->FieldOfView; UE_LOG(LogTemp, Display, TEXT("Original Camera Location: %s"), *OriginalCameraLocation.ToString()); } } void ATempCharacter::InputEnabler() { //Enable Character Movement if (ACharacter* PlayerCharacter = Cast(GetWorld()->GetFirstPlayerController()->GetPawn())) { PlayerCharacter->EnableInput(GetWorld()->GetFirstPlayerController()); } //Reset UI Mode APlayerController* PlayerController = GetWorld()->GetFirstPlayerController(); PlayerController->SetInputMode(FInputModeGameOnly()); PlayerController->bShowMouseCursor = false; UE_LOG(LogTemp, Display, TEXT("Enabling Inputs")); disableTab = true; TraceDistance = 300; if (ThisCamera != nullptr) { ThisCamera->SetWorldLocation(OriginalCameraLocation); ThisCamera->SetWorldRotation(OriginalCameraRotation); ThisCamera->FieldOfView = OriginalCameraFOV; UE_LOG(LogTemp, Display, TEXT("Original Camera Location: %s"), *OriginalCameraLocation.ToString()); } } 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(); }