// 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 "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(); FirstPlayerController = GetWorld()->GetFirstPlayerController(); CombatSystem = Cast(GetWorld()->GetGameState()); WidgetPointer = Cast(this->GetComponentByClass(UWidgetInteractionComponent::StaticClass())); 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; } else { Crouch(); isInStealth = true; if (PostProcessVolume != nullptr) PostProcessVolume->Settings.VignetteIntensity = 0.8f; } } void ATempCharacter::ResetWidgetPointer() const { WidgetPointer->SetWorldLocationAndRotation(FVector(0, 0, 0), FRotator(0, 0, 0).Quaternion()); } // Called every frame void ATempCharacter::Tick(float DeltaTime) { Super::Tick(DeltaTime); if (CombatSystem->bIsInCombat) { FVector VectorRotation; FVector WidgetLocation; FirstPlayerController->DeprojectMousePositionToWorld(WidgetLocation, VectorRotation); WidgetPointer->SetWorldLocationAndRotation(WidgetLocation, VectorRotation.Rotation().Quaternion()); } } // 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; 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_Pawn, TraceParams); if (bHit) { if (OutHit.GetActor() == nullptr) { return; } if(OutHit.GetActor()->ActorHasTag(TEXT("Probertium"))) { AddToInventory(); return; } if(OutHit.GetActor()->ActorHasTag(TEXT("Iroquid"))) { AddToInventory(); return; } if (OutHit.GetActor()->ActorHasTag(TEXT("Azos"))) { AddToInventory(); return; } if (OutHit.GetActor()->ActorHasTag(TEXT("Eis"))) { AddToInventory(); 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 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::AddToInventory() { 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")); } OutHit.GetActor()->Destroy(); } } void ATempCharacter::InputDisabler() { //Disable Character Movement if (ACharacter* PlayerCharacter = Cast(GetWorld()->GetFirstPlayerController()->GetPawn())) { PlayerCharacter->DisableInput(GetWorld()->GetFirstPlayerController()); } //TURNING OFF CROSSHAIR CrossHairWidget->SetVisibility(ESlateVisibility::Hidden); //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(AActor* Item) { if (Item == nullptr) { UE_LOG(LogTemp, Display, TEXT("Item is null")); return; } else { UBaseItem* ItemArray = Item->FindComponentByClass()->GetItem(0); if (GoldBalance <= 0) { UE_LOG(LogTemp, Display, TEXT("Not Enough Gold")); } else if (GoldBalance >= ItemArray->ItemCostPrice) { GoldBalance -= ItemArray->ItemCostPrice; Inventory->AddItem(ItemArray); UE_LOG(LogTemp, Display, TEXT("Item Purchased")); } UE_LOG(LogTemp, Display, TEXT("BUY ITEM FIRING")); TraceDistance = 1000; LineTraceLogic(); } }