Advertisement
Guest User

PersonCharacter.cpp

a guest
Apr 15th, 2015
273
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.92 KB | None | 0 0
  1. // Fill out your copyright notice in the Description page of Project Settings.
  2.  
  3. #include "GetDebt.h"
  4. #include "PersonCharacter.h"
  5. #include "../Player/Machine/BaseFrame.h"
  6. #include "../GetDebtGameMode.h"
  7. #include "PersonAIController.h"
  8.  
  9. APersonCharacter::APersonCharacter(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer.SetDefaultSubobjectClass<UMovementComponent>(TEXT("Movement")))
  10. {
  11.     // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.    
  12.     PrimaryActorTick.bCanEverTick = true;
  13.  
  14.     this->AIControllerClass = APersonAIController::StaticClass();
  15.  
  16.     this->BoxCollision = ObjectInitializer.CreateDefaultSubobject<UBoxComponent>(this, "CollisionComponent");
  17.     this->BoxCollision->SetSimulatePhysics(true);
  18.     this->BoxCollision->SetCollisionProfileName(TEXT("Pawn"));
  19.     this->BoxCollision->SetEnableGravity(false);
  20.     this->BoxCollision->SetLinearDamping(1.0f);
  21.     this->BoxCollision->SetBoxExtent(FVector(50.0f, 50.0f, 50.0f));
  22.     this->BoxCollision->SetRelativeLocation(FVector(0.0f, 0.0f, 50.0f));
  23.     this->BoxCollision->bShouldUpdatePhysicsVolume = true;
  24.     this->SetRootComponent(this->BoxCollision);
  25.  
  26.     this->SensingComponent = ObjectInitializer.CreateDefaultSubobject<UPawnSensingComponent>(this, TEXT("SensingComponent"));
  27.     this->MaxMoveSpeed = 50.0f;
  28.  
  29.     this->DebugArrow = ObjectInitializer.CreateDefaultSubobject<UArrowComponent>(this, TEXT("DebugArrow"));
  30.     this->DebugArrow->SetRelativeLocation(FVector::ZeroVector);
  31.  
  32.     this->TargetLocation = FVector::ZeroVector;
  33. }
  34.  
  35. // Called when the game starts or when spawned
  36. void APersonCharacter::BeginPlay()
  37. {
  38.     Super::BeginPlay();
  39.  
  40.     //Note(Thompson): Will return NULL if this is called on a network client.
  41.     //We need to have some global references in our game, so each actor can interact with all of them nicely.
  42.     AGetDebtGameMode* GetDebtMode = (AGetDebtGameMode*) this->GetWorld()->GetAuthGameMode();
  43.     if (GetDebtMode != NULL || GetDebtMode != nullptr){
  44.         GetDebtMode->PeopleArray.Push(this);
  45.     }
  46. }
  47.  
  48. // Called every frame
  49. void APersonCharacter::Tick(float DeltaTime)
  50. {
  51.     Super::Tick(DeltaTime);
  52.  
  53.     AGameMode* GameMode = this->GetWorld()->GetAuthGameMode();
  54.     AGetDebtGameMode* GetDebtMode = CastChecked<AGetDebtGameMode>(GameMode);
  55.     ABaseFrame* MainBaseFrame = GetDebtMode->MainBaseFrame;
  56.     APersonAIController* Controller = CastChecked<APersonAIController>(this->GetController());
  57.     if (Controller == nullptr || Controller == NULL){
  58.         check(0 && "Unable to obtain PersonAIController.");
  59.     }
  60.  
  61.     //If we aren't at the target location
  62.     if (!this->IsAtTargetLocation())
  63.     {
  64.         UpdateMovement(DeltaTime);
  65.     }
  66.     else if ((Controller == nullptr) || (Controller == NULL)){
  67.         if (this->CanSeeMachine()){
  68.             //Can see machine
  69.             Controller->StateMachine->SwitchState(EFSMState::EFSM_RunAway);
  70.         }
  71.         else if ((MainBaseFrame == nullptr || MainBaseFrame == NULL) && (this->IsPersonInRangeToPlayer(MainBaseFrame, this, 500.0f))){
  72.             Controller->StateMachine->SwitchState(EFSMState::EFSM_Hide);
  73.         }
  74.         else {
  75.             Controller->StateMachine->SwitchState(EFSMState::EFSM_Wander);
  76.         }
  77.     }
  78. }
  79.  
  80. // Called to bind functionality to input
  81. void APersonCharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent)
  82. {
  83.     Super::SetupPlayerInputComponent(InputComponent);
  84. }
  85.  
  86. bool APersonCharacter::CanSeeMachine(){
  87.     //Note (Robert) New code using PawnSensing
  88.     if (this->GetController() != nullptr){
  89.         this->TempController = CastChecked<APersonAIController>(this->GetController());
  90.         if ((this->TempController != nullptr) && (this->TempController->ClosestPlayerController != nullptr) && (this->TempController->ClosestPlayerController->GetPawn() != nullptr)){
  91.             //FIXME (Thompson): Unhandled exception, where the variable, Controller, is optimized away by Visual Studio. You need to add UPROPERTY() to Controller, else
  92.             //it will get garbage collected by UE API.
  93.             bool Result = this->SensingComponent->HasLineOfSightTo(this->TempController->ClosestPlayerController->GetPawn());
  94.             LOG("CanSeeMachine() Value: " + FString((Result ? "True" : "False")));
  95.             return Result;
  96.         }
  97.     }
  98. #ifdef DEBUG
  99.     if (this->TempController == nullptr){
  100.         LOG("TempController is NULL.");
  101.     }
  102.     else if (this->TempController->ClosestPlayerController == nullptr) {
  103.         LOG("Closest player controller is NULL.");
  104.     }
  105.     else if (this->TempController->ClosestPlayerController->GetPawn() == nullptr) {
  106.         LOG("Pawn returned from closest player controller is NULL.");
  107.     }
  108. #endif
  109.     return false;
  110. }
  111.  
  112. void APersonCharacter::MoveTowardsTarget(FVector NewTargetLocation)
  113. {
  114.     //TODO(Robert) Do we even need this function?
  115.     //Note(Thompson): We might need to.
  116.     this->TargetLocation = NewTargetLocation;
  117.     this->TargetLocation.Z = 0.0f;
  118.  
  119.     /*FVector StartingLocation = this->GetActorLocation();*/
  120. }
  121.  
  122. void APersonCharacter::UpdateMovement(float DeltaTime)
  123. {
  124.     FVector CurrentLocation = this->GetActorLocation(); //Optimized away.
  125.  
  126.     FVector TempTargetLocation(this->TargetLocation);
  127.     FVector TempCurrentLocation(CurrentLocation);
  128.     TempTargetLocation.Z = TempCurrentLocation.Z = 0.0f;
  129.  
  130.  
  131.  
  132.     float DistancetoTargetLocation = FVector::Dist(TempTargetLocation, TempCurrentLocation);
  133.     float Deceleration = 100.0f;
  134.     float Speed = DistancetoTargetLocation / Deceleration;
  135.  
  136.     Speed = FMath::Min(Speed, MaxMoveSpeed);
  137.  
  138.     FVector ToTarget = TempTargetLocation - TempCurrentLocation;
  139.  
  140.     //Calculate new velocity
  141.     FVector ChangeInVelocityNeeded = ToTarget * Speed / DistancetoTargetLocation;
  142.  
  143.     //Note(Thompson): FVector to FRotator
  144.     FVector TempDistance = TempCurrentLocation - TempTargetLocation;
  145.     TempDistance.Normalize();
  146.     FRotator NewRotation = TempDistance.Rotation();
  147.  
  148.     //Note(Thompson): Nullifying pitch and roll.
  149.     NewRotation.Pitch = 0.0f;
  150.     NewRotation.Roll = 0.0f;
  151.  
  152.     //Apply new Rotation
  153.     this->ClientSetRotation(NewRotation); //TODO Can we make this not instant? Should we?
  154.  
  155.  
  156.     if (BoxCollision != nullptr) {
  157.         this->BoxCollision->SetWorldRotation(NewRotation);
  158.         float Mass = this->BoxCollision->GetMass();
  159.         FVector ActualMomentum = ChangeInVelocityNeeded * Mass;
  160.         ActualMomentum.Z = 0.0f;
  161.         this->BoxCollision->AddForce(ActualMomentum / DeltaTime);
  162.         FRotator ChangedRotation = ChangeInVelocityNeeded.Rotation();
  163.         ChangedRotation.Pitch = ChangedRotation.Roll = 0.0f;
  164.         this->BoxCollision->SetRelativeRotation(ChangedRotation);
  165.     }
  166. }
  167.  
  168. bool APersonCharacter::IsAtTargetLocation(){
  169.     bool Result = (FVector::Dist(this->TargetLocation, this->GetActorLocation()) < 250.0f);
  170.     return Result;
  171. }
  172.  
  173. bool APersonCharacter::IsPersonInRangeToPlayer(ABaseFrame* HuntingPlayer, APersonCharacter* HuntedPerson, float Distance){
  174.     FVector PlayerLocation = HuntingPlayer->GetActorLocation();
  175.     FVector PersonLocation = HuntedPerson->GetActorLocation();
  176.  
  177. #ifdef DEBUG
  178.     DrawDebugSphere(this->GetWorld(), PersonLocation, Distance, 32, FColor::Blue, false, 2.5f);
  179. #endif
  180.  
  181.     if (FMath::Abs<float>((FVector::Dist(PlayerLocation, PersonLocation)) <= Distance)){
  182.         return true;
  183.     }
  184.     return false;
  185. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement