funny-prince/Source/FunnyPrince/FunnyPrinceCharacter.cpp

206 lines
5.4 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "FunnyPrinceCharacter.h"
#include "SSTCharacterMovementComponent.h"
#include "EnhancedInputComponent.h"
#include "Components/ArrowComponent.h"
#include "EnhancedInputComponent.h"
#include "Engine/DamageEvents.h"
#include "EnemyCharacter.h"
#include "FunnyPrinceGameMode.h"
#include "Components/CapsuleComponent.h"
DEFINE_LOG_CATEGORY(LogTemplateFunnyPrinceCharacter);
//////////////////////////////////////////////////////////////////////////
// AFunnyPrinceCharacter
AFunnyPrinceCharacter::AFunnyPrinceCharacter(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer),
MoveAction2(nullptr),
PunchAction(nullptr),
PunchMontage(nullptr),
StartAttack(nullptr),
EndAttack(nullptr),
CanAttack(true),
MaxHealth(100),
Health(100),
PunchDamage(10),
CanMove(true)
{
StartAttack = CreateDefaultSubobject<UArrowComponent>("StartAttack");
StartAttack->SetupAttachment(RootComponent);
StartAttack->SetRelativeLocation(FVector(60.f, 0.f, 40.f));
StartAttack->SetArrowSize(0.5f);
StartAttack->SetArrowLength(30.f);
EndAttack = CreateDefaultSubobject<UArrowComponent>("EndAttack");
EndAttack->SetupAttachment(RootComponent);
EndAttack->SetRelativeLocation(FVector(105.f, 0.f, 40.f));
EndAttack->SetArrowSize(0.5f);
EndAttack->SetArrowLength(30.f);
}
void AFunnyPrinceCharacter::BeginPlay()
{
// Call the base class
Super::BeginPlay();
Health = MaxHealth;
}
//////////////////////////////////////////////////////////////////////////
// Input
void AFunnyPrinceCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
// Set up action bindings
if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent)) {
//Moving
EnhancedInputComponent->BindAction(MoveAction2, ETriggerEvent::Triggered, this, &AFunnyPrinceCharacter::Move);
// Punching
EnhancedInputComponent->BindAction(PunchAction, ETriggerEvent::Started, this, &AFunnyPrinceCharacter::StartPunch);
}
}
void AFunnyPrinceCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
float AFunnyPrinceCharacter::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator,
AActor* DamageCauser)
{
float DamageToApply = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);
DamageToApply = FMath::Min(Health, DamageToApply);
Health -= DamageToApply;
if (Health <= 0)
{
Health = 0;
AFunnyPrinceGameMode* GameMode = GetWorld()->GetAuthGameMode<AFunnyPrinceGameMode>();
if (GameMode)
{
GameMode->PawnKilled(this);
}
DetachFromControllerPendingDestroy();
GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
SetLifeSpan(0.f);
}
UE_LOG(LogTemp, Warning, TEXT("Actor hit for %f damage. Current HP: %f"), DamageToApply, Health);
return DamageToApply;
}
bool AFunnyPrinceCharacter::IsDead() const
{
return (Health <= 0);
}
float AFunnyPrinceCharacter::GetHealthPercent() const
{
return Health / MaxHealth;
}
bool AFunnyPrinceCharacter::CanJumpInternal_Implementation() const
{
USSTCharacterMovementComponent* Movement = Cast<USSTCharacterMovementComponent>(GetCharacterMovement());
if (Movement)
{
return Super::CanJumpInternal_Implementation() || Movement->CanWalljump();
}
return Super::CanJumpInternal_Implementation();
}
void AFunnyPrinceCharacter::StartPunch()
{
if (!CanAttack) return;
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
if (AnimInstance && PunchMontage)
{
UE_LOG(LogTemp, Warning, TEXT("StartPunch()"));
CanAttack = false;
CanMove = false;
AnimInstance->Montage_Play(PunchMontage);
//AnimInstance->Montage_JumpToSection(FName("StartFire"));
}
//GetCharacterMovement()->IsFalling();
}
void AFunnyPrinceCharacter::FinishPunching()
{
CanMove = true;
CanAttack = true;
}
void AFunnyPrinceCharacter::PunchHitTrace()
{
// Trace hit
FHitResult PunchTraceHit;
if (StartAttack && EndAttack)
{
FVector start = StartAttack->GetSocketLocation(FName());
FVector end = EndAttack->GetSocketLocation(FName());
/*FCollisionQueryParams Params;
Params.AddIgnoredActor(this);*/
bool bSuccess = GetWorld()->LineTraceSingleByChannel(PunchTraceHit, start, end, ECollisionChannel::ECC_GameTraceChannel1);
if (bSuccess)
{
AFunnyPrinceCharacter* HitEnemy = Cast<AFunnyPrinceCharacter>(PunchTraceHit.GetActor());
if (HitEnemy)
{
FPointDamageEvent DamageEvent(PunchDamage, PunchTraceHit, end - start, nullptr);
HitEnemy->TakeDamage(PunchDamage, DamageEvent, GetController(), this);
UAnimInstance* AnimInstance = HitEnemy->GetMesh()->GetAnimInstance();
if (AnimInstance && PunchReactionMontage)
{
UE_LOG(LogTemp, Warning, TEXT("Punch Reaction"));
HitEnemy->CanAttack = false;
HitEnemy->CanMove = false;
AnimInstance->Montage_Play(PunchReactionMontage);
}
}
}
/*UE_LOG(LogTemp, Warning, TEXT("TraceHit from %f %f %f to %f %f %f"),
start.X,
start.Y,
start.Z,
end.X,
end.Y,
end.Z);*/
// (World, Start, End, Color, Persistent Lines, Life Time, Depth Priority, Thickness)
//DrawDebugLine(GetWorld(), start, end, FColor(255, 0, 0), false, 1, 0, 5);
}
}
void AFunnyPrinceCharacter::FinishPunchReaction()
{
CanMove = true;
CanAttack = true;
}
void AFunnyPrinceCharacter::Move(const FInputActionValue& Value)
{
if (CanMove)
{
Super::Move(Value);
}
}