236 lines
6.4 KiB
C++
236 lines
6.4 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
|
|
#include "Player/LMPlayer.h"
|
|
|
|
#include "KismetTraceUtils.h"
|
|
#include "LMUserSettings.h"
|
|
#include "LMUtils.h"
|
|
#include "Camera/CameraComponent.h"
|
|
#include "Ammo/LMAmmo.h"
|
|
#include "Player/LMBulletInfo.h"
|
|
#include "Player/LMHealthComponent.h"
|
|
#include "Player/LMHitBox.h"
|
|
#include "Player/LMMovementComponent.h"
|
|
#include "Weapon/LMWeaponManager.h"
|
|
|
|
|
|
ALMPlayer::ALMPlayer(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer.SetDefaultSubobjectClass<ULMMovementComponent>(CharacterMovementComponentName))
|
|
{
|
|
LegumixMovementComponent = Cast<ULMMovementComponent>(GetCharacterMovement());
|
|
|
|
PrimaryActorTick.bCanEverTick = true;
|
|
|
|
SpreadStream = FRandomStream(FMath::Rand());
|
|
HealthComponent = CreateDefaultSubobject<ULMHealthComponent>(TEXT("HealthComponent"));
|
|
|
|
HitPeriodLengthInSeconds = 15.f;
|
|
bHitPeriodInProgress = false;
|
|
TimeOfTheLastDamage = 0.f;
|
|
HealthAtTheCurrentHitPeriodBeginning = 100.f;
|
|
CumulatedDamagesOnCurrentHitPeriod = 0.f;
|
|
PlayerViewOcclusionPercent = 0.f;
|
|
NextPlayerViewOcclusionPercent = 0.f;
|
|
PlayerViewOcclusionPercent = 0.f;
|
|
AlphaLerpForPlayerViewOcclusionPercent = 0.f;
|
|
}
|
|
|
|
void ALMPlayer::BeginPlay()
|
|
{
|
|
Super::BeginPlay();
|
|
WeaponManager->WeaponFired.AddUniqueDynamic(this, &ALMPlayer::WeaponFired);
|
|
WeaponManager->WeaponSwitched.AddUniqueDynamic(this, &ALMPlayer::WeaponSwitched);
|
|
|
|
GetCamera()->SetFieldOfView(ULMUserSettings::GetLegumixUserSettings()->FieldOfView);
|
|
|
|
HealthComponent->OnHealthChanged.AddDynamic(this, &ALMPlayer::SetDisplayDamageParameters);
|
|
}
|
|
|
|
void ALMPlayer::Tick(float DeltaTime)
|
|
{
|
|
if(bHitPeriodInProgress == true)
|
|
{
|
|
double TimeElapsedSinceLastDamage = GetWorld()->GetTimeSeconds() - TimeOfTheLastDamage;
|
|
if(TimeElapsedSinceLastDamage > HitPeriodLengthInSeconds)
|
|
{
|
|
if(bHitPeriodInProgress == true)
|
|
{
|
|
bHitPeriodInProgress = false;
|
|
PlayerViewOcclusionPercent = NextPlayerViewOcclusionPercent;
|
|
NextPlayerViewOcclusionPercent = 0.f;
|
|
AlphaLerpForPlayerViewOcclusionPercent = 0.f;
|
|
TimeOfTheLastDamage = 0.f;
|
|
CumulatedDamagesOnCurrentHitPeriod = 0.f;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(PlayerViewOcclusionPercent != NextPlayerViewOcclusionPercent)
|
|
{
|
|
AlphaLerpForPlayerViewOcclusionPercent = FMath::Clamp(AlphaLerpForPlayerViewOcclusionPercent + DeltaTime, 0, 1);
|
|
PlayerViewOcclusionPercent = FMath::Lerp(PlayerViewOcclusionPercent, NextPlayerViewOcclusionPercent, AlphaLerpForPlayerViewOcclusionPercent);
|
|
DamageDynamicMaterialInstance->SetScalarParameterValue("PlayerViewOcclusionPercent", PlayerViewOcclusionPercent);
|
|
}
|
|
else if(PlayerViewOcclusionPercent == NextPlayerViewOcclusionPercent)
|
|
{
|
|
AlphaLerpForPlayerViewOcclusionPercent = 0;
|
|
}
|
|
}
|
|
|
|
|
|
bool ALMPlayer::PickUpAmmo(ALMAmmo* Ammo)
|
|
{
|
|
if (GEngine)
|
|
{
|
|
const FString AmmoAmount = FString::Printf(TEXT("Quantité de munition : %i"), Ammo->GetAmmoAmount());
|
|
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 30.f, FColor::Red, AmmoAmount);
|
|
}
|
|
|
|
if (WeaponManager->AddAmmoType(Ammo->GetAmmoType(), Ammo->GetAmmoAmount()))
|
|
{
|
|
OnAmmoPickup();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int ALMPlayer::GetAmmoCount(const EAmmoType AmmoType) const
|
|
{
|
|
return WeaponManager->GetAmmoCount(AmmoType);
|
|
}
|
|
|
|
int ALMPlayer::RemoveAmmo(const EAmmoType AmmoType, const int Count) const
|
|
{
|
|
return WeaponManager->RemoveAmmo(AmmoType, Count);
|
|
}
|
|
|
|
void ALMPlayer::SetWeaponManager(ULMWeaponManager* Manager)
|
|
{
|
|
UE_LOG(LogTemp, Warning, TEXT("Set weapon manager"))
|
|
if (!Manager)
|
|
{
|
|
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 10.f, FColor::Red, TEXT("No Weapon Manager was given to the player !"));
|
|
return;
|
|
}
|
|
|
|
WeaponManager = Manager;
|
|
WeaponManager->Initialize(GetArms());
|
|
}
|
|
|
|
void ALMPlayer::PlayAnimation(UAnimMontage* Animation)
|
|
{
|
|
}
|
|
|
|
void ALMPlayer::FireBullets(const FLMBulletInfo Settings)
|
|
{
|
|
FVector EndLocation;
|
|
FVector ShotVector;
|
|
FHitResult OutHit = FHitResult();
|
|
bool HitSomething = false;
|
|
|
|
OnFire();
|
|
|
|
#if WITH_EDITOR
|
|
if (bDrawBulletDebug)
|
|
DrawDebugLine(GetWorld(), Settings.Origin, Settings.Origin + (Settings.Direction * Settings.MaxDistance), FColor::Blue, false, 2.f);
|
|
#endif
|
|
|
|
for (int Shots = 0; Shots < Settings.BulletCount; Shots++)
|
|
{
|
|
ShotVector = UKismetMathLibrary::RandomUnitVectorInConeInDegreesFromStream(SpreadStream, Settings.Direction, Settings.Spread);
|
|
EndLocation = Settings.Origin + (ShotVector * Settings.MaxDistance);
|
|
|
|
const bool HasHit = GetWorld()->LineTraceSingleByChannel(OutHit, Settings.Origin, EndLocation, TRACE_BULLET);
|
|
|
|
#if WITH_EDITOR
|
|
if (bDrawBulletDebug)
|
|
DrawDebugLineTraceSingle(GetWorld(), Settings.Origin, EndLocation, EDrawDebugTrace::ForDuration, HasHit, OutHit, FColor::Green, FColor::Red, 2.f);
|
|
#endif
|
|
|
|
WeaponManager->CreateTracer(Settings.AmmoType, HasHit ? OutHit.Location : EndLocation, ShotVector.Rotation());
|
|
|
|
if (!HasHit)
|
|
continue;
|
|
|
|
if (ULMHitBox* HitBox = Cast<ULMHitBox>(OutHit.Component))
|
|
{
|
|
if (!HitBox->CanBeHitByTeam(Team))
|
|
continue;
|
|
|
|
HitSomething = true;
|
|
HitBox->OnHit(Settings);
|
|
}
|
|
}
|
|
|
|
if (HitSomething)
|
|
{
|
|
OnEnnemyHit();
|
|
}
|
|
}
|
|
|
|
FVector ALMPlayer::GetWeaponFiringOrigin()
|
|
{
|
|
if (!GetCam())
|
|
{
|
|
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 10.f, FColor::Silver, TEXT("No camera ???"));
|
|
return FVector::ZeroVector;
|
|
}
|
|
return GetCam()->GetComponentTransform().GetLocation();
|
|
}
|
|
|
|
FVector ALMPlayer::GetAimVector() { return GetCam()->GetForwardVector(); }
|
|
|
|
void ALMPlayer::OnPause_Implementation(bool Paused)
|
|
{
|
|
}
|
|
|
|
UCameraComponent* ALMPlayer::GetCam()
|
|
{
|
|
if (!Camera)
|
|
Camera = GetCamera();
|
|
|
|
return Camera;
|
|
}
|
|
|
|
USkeletalMeshComponent* ALMPlayer::GetArms()
|
|
{
|
|
if (!ArmsMesh)
|
|
ArmsMesh = GetArmsBP();
|
|
|
|
return ArmsMesh;
|
|
}
|
|
|
|
void ALMPlayer::SetDisplayDamageParameters(float Health, float Damage)
|
|
{
|
|
if (bHitPeriodInProgress == false)
|
|
{
|
|
HealthAtTheCurrentHitPeriodBeginning = Health;
|
|
bHitPeriodInProgress = true;
|
|
}
|
|
TimeOfTheLastDamage = GetWorld()->GetTimeSeconds();
|
|
CumulatedDamagesOnCurrentHitPeriod += Damage;
|
|
SetPlayerViewOcclusionPercent();
|
|
}
|
|
|
|
|
|
void ALMPlayer::SetPlayerViewOcclusionPercent()
|
|
{
|
|
AlphaLerpForPlayerViewOcclusionPercent = 0;
|
|
PlayerViewOcclusionPercent = NextPlayerViewOcclusionPercent;
|
|
NextPlayerViewOcclusionPercent = CumulatedDamagesOnCurrentHitPeriod / HealthAtTheCurrentHitPeriodBeginning;
|
|
}
|
|
|
|
FCollisionQueryParams ALMPlayer::GetIgnoreCharacterParams()
|
|
{
|
|
FCollisionQueryParams Params;
|
|
|
|
TArray<AActor*> ChildrenActors;
|
|
GetAllChildActors(ChildrenActors);
|
|
Params.AddIgnoredActors(ChildrenActors);
|
|
Params.AddIgnoredActor(this);
|
|
|
|
return Params;
|
|
}
|
|
|