Some bug fixes and reorg

This commit is contained in:
Kingsmedia 2022-05-29 11:59:15 +02:00
parent 4fa586e648
commit d2e581afe5
18 changed files with 477 additions and 523 deletions

View File

@ -49,11 +49,11 @@ ABlasterCharacter::ABlasterCharacter()
Combat = CreateDefaultSubobject<UCombatComponent>(TEXT("CombatComponent"));
Combat->SetIsReplicated(true);
LagCompensation = CreateDefaultSubobject<ULagCompensationComponent>(TEXT("LagCompensation"));
Buff = CreateDefaultSubobject<UBuffComponent>(TEXT("BuffComponent"));
Buff->SetIsReplicated(true);
LagCompensation = CreateDefaultSubobject<ULagCompensationComponent>(TEXT("LagCompensation"));
GetCharacterMovement()->NavAgentProps.bCanCrouch = true;
GetCapsuleComponent()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Ignore);
GetMesh()->SetCollisionObjectType(ECC_SkeletalMesh);
@ -113,14 +113,14 @@ ABlasterCharacter::ABlasterCharacter()
hand_r->SetupAttachment(GetMesh(), FName("hand_r"));
HitCollisionBoxes.Add(FName("hand_r"), hand_r);
backpack = CreateDefaultSubobject<UBoxComponent>(TEXT("backpack"));
backpack->SetupAttachment(GetMesh(), FName("backpack"));
HitCollisionBoxes.Add(FName("backpack"), backpack);
blanket = CreateDefaultSubobject<UBoxComponent>(TEXT("blanket"));
blanket->SetupAttachment(GetMesh(), FName("backpack"));
HitCollisionBoxes.Add(FName("blanket"), blanket);
backpack = CreateDefaultSubobject<UBoxComponent>(TEXT("backpack"));
backpack->SetupAttachment(GetMesh(), FName("backpack"));
HitCollisionBoxes.Add(FName("backpack"), backpack);
thigh_l = CreateDefaultSubobject<UBoxComponent>(TEXT("thigh_l"));
thigh_l->SetupAttachment(GetMesh(), FName("thigh_l"));
HitCollisionBoxes.Add(FName("thigh_l"), thigh_l);
@ -200,9 +200,9 @@ void ABlasterCharacter::MulticastEliminated_Implementation(bool bPlayerLeftGame)
StartDissolve();
// Disable character movement
bDisableGameplay = true;
GetCharacterMovement()->DisableMovement();
GetCharacterMovement()->StopMovementImmediately();
bDisableGameplay = true;
if (Combat)
{
Combat->FireButtonPressed(false);
@ -280,10 +280,9 @@ void ABlasterCharacter::Destroyed()
ABlasterGameMode* BlasterGameMode = Cast<ABlasterGameMode>(UGameplayStatics::GetGameMode(this));
bool bMatchNotInProgress = BlasterGameMode && BlasterGameMode->GetMatchState() != MatchState::InProgress;
if (Combat && Combat->PrimaryWeapon && bMatchNotInProgress)
if (Combat && Combat->EquippedWeapon && bMatchNotInProgress)
{
Combat->PrimaryWeapon->Destroy();
Combat->EquippedWeapon->Destroy();
}
}
@ -302,7 +301,6 @@ void ABlasterCharacter::MulticastGainedTheLead_Implementation()
false
);
}
if (CrownComponent)
{
CrownComponent->Activate();
@ -320,7 +318,6 @@ void ABlasterCharacter::MulticastLostTheLead_Implementation()
void ABlasterCharacter::BeginPlay()
{
Super::BeginPlay();
SpawnDefaultWeapon();
UpdateHUDAmmo();
UpdateHUDHealth();
@ -413,7 +410,7 @@ void ABlasterCharacter::PostInitializeComponents()
void ABlasterCharacter::PlayFireMontage(bool bAiming)
{
if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return;
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
if (AnimInstance && FireWeaponMontage)
@ -427,7 +424,7 @@ void ABlasterCharacter::PlayFireMontage(bool bAiming)
void ABlasterCharacter::PlayReloadMontage()
{
if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return;
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
if (AnimInstance && ReloadMontage)
@ -435,7 +432,7 @@ void ABlasterCharacter::PlayReloadMontage()
AnimInstance->Montage_Play(ReloadMontage);
FName SectionName;
switch (Combat->PrimaryWeapon->GetWeaponType())
switch (Combat->EquippedWeapon->GetWeaponType())
{
case EWeaponType::EWT_AssaultRifle:
SectionName = FName("Rifle");
@ -496,7 +493,7 @@ void ABlasterCharacter::PlaySwapMontage()
void ABlasterCharacter::PlayHitReactMontage()
{
if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return;
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
if (AnimInstance && HitReactMontage)
@ -507,6 +504,14 @@ void ABlasterCharacter::PlayHitReactMontage()
}
}
void ABlasterCharacter::GrenadeButtonPressed()
{
if (Combat)
{
Combat->ThrowGrenade();
}
}
void ABlasterCharacter::ReceiveDamage(AActor* DamagedActor, float Damage, const UDamageType* DamageType, AController* InstigatorController, AActor* DamageCauser)
{
if (bEliminated) return;
@ -521,8 +526,8 @@ void ABlasterCharacter::ReceiveDamage(AActor* DamagedActor, float Damage, const
}
else
{
DamageToHealth = FMath::Clamp(DamageToHealth - (Damage - Shield), 0.f, Damage);
Shield = 0.f;
DamageToHealth = FMath::Clamp(DamageToHealth - (Damage - Shield), 0.f, Damage);
}
}
@ -654,14 +659,6 @@ void ABlasterCharacter::AimButtonReleased()
}
}
void ABlasterCharacter::GrenadeButtonPressed()
{
if (Combat)
{
Combat->ThrowGrenade();
}
}
float ABlasterCharacter::CalculateSpeed()
{
FVector Velocity = GetVelocity();
@ -671,7 +668,7 @@ float ABlasterCharacter::CalculateSpeed()
void ABlasterCharacter::AimOffset(float DeltaTime)
{
if (Combat && Combat->PrimaryWeapon == nullptr) return;
if (Combat && Combat->EquippedWeapon == nullptr) return;
float Speed = CalculateSpeed();
bool bIsInAir = GetCharacterMovement()->IsFalling();
@ -714,7 +711,7 @@ void ABlasterCharacter::CalculateAO_Pitch()
void ABlasterCharacter::SimProxiesTurn()
{
if (Combat == nullptr || Combat->PrimaryWeapon == nullptr) return;
if (Combat == nullptr || Combat->EquippedWeapon == nullptr) return;
bRotateRootBone = false;
float Speed = CalculateSpeed();
if (Speed > 0.f)
@ -806,9 +803,9 @@ void ABlasterCharacter::HideCameraIfCharacterClose()
if ((FollowCamera->GetComponentLocation() - GetActorLocation()).Size() < CameraThreshold)
{
GetMesh()->SetVisibility(false);
if (Combat && Combat->PrimaryWeapon && Combat->PrimaryWeapon->GetWeaponMesh())
if (Combat && Combat->EquippedWeapon && Combat->EquippedWeapon->GetWeaponMesh())
{
Combat->PrimaryWeapon->GetWeaponMesh()->bOwnerNoSee = true;
Combat->EquippedWeapon->GetWeaponMesh()->bOwnerNoSee = true;
}
if (Combat && Combat->SecondaryWeapon && Combat->SecondaryWeapon->GetWeaponMesh())
{
@ -818,9 +815,9 @@ void ABlasterCharacter::HideCameraIfCharacterClose()
else
{
GetMesh()->SetVisibility(true);
if (Combat && Combat->PrimaryWeapon && Combat->PrimaryWeapon->GetWeaponMesh())
if (Combat && Combat->EquippedWeapon && Combat->EquippedWeapon->GetWeaponMesh())
{
Combat->PrimaryWeapon->GetWeaponMesh()->bOwnerNoSee = false;
Combat->EquippedWeapon->GetWeaponMesh()->bOwnerNoSee = false;
}
if (Combat && Combat->SecondaryWeapon && Combat->SecondaryWeapon->GetWeaponMesh())
{
@ -868,10 +865,10 @@ void ABlasterCharacter::UpdateHUDShield()
void ABlasterCharacter::UpdateHUDAmmo()
{
BlasterPlayerController = BlasterPlayerController == nullptr ? Cast<ABlasterPlayerController>(Controller) : BlasterPlayerController;
if (BlasterPlayerController && Combat && Combat->PrimaryWeapon)
if (BlasterPlayerController && Combat && Combat->EquippedWeapon)
{
BlasterPlayerController->SetHUDCarriedAmmo(Combat->CarriedAmmo);
BlasterPlayerController->SetHUDWeaponAmmo(Combat->PrimaryWeapon->GetAmmo());
BlasterPlayerController->SetHUDWeaponAmmo(Combat->EquippedWeapon->GetAmmo());
}
}
@ -908,7 +905,6 @@ void ABlasterCharacter::PollInit()
}
}
}
}
void ABlasterCharacter::UpdateDissolveMaterial(float DissolveValue)
@ -959,7 +955,7 @@ void ABlasterCharacter::OnRep_OverlappingWeapon(AWeapon* LastWeapon)
bool ABlasterCharacter::IsWeaponEquipped()
{
return Combat && Combat->PrimaryWeapon;
return Combat && Combat->EquippedWeapon;
}
bool ABlasterCharacter::IsAiming()
@ -970,7 +966,7 @@ bool ABlasterCharacter::IsAiming()
AWeapon* ABlasterCharacter::GetPrimaryWeapon()
{
if (Combat == nullptr) return nullptr;
return Combat->PrimaryWeapon;
return Combat->EquippedWeapon;
}
FVector ABlasterCharacter::GetHitTarget() const

View File

@ -25,7 +25,7 @@ void UCombatComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& Out
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(UCombatComponent, PrimaryWeapon);
DOREPLIFETIME(UCombatComponent, EquippedWeapon);
DOREPLIFETIME(UCombatComponent, SecondaryWeapon);
DOREPLIFETIME(UCombatComponent, bAiming);
DOREPLIFETIME_CONDITION(UCombatComponent, CarriedAmmo, COND_OwnerOnly);
@ -33,6 +33,14 @@ void UCombatComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& Out
DOREPLIFETIME(UCombatComponent, Grenades);
}
void UCombatComponent::ShotgunShellReload()
{
if (Character && Character->HasAuthority())
{
UpdateShotgunAmmoValues();
}
}
void UCombatComponent::PickupAmmo(EWeaponType WeaponType, int32 AmmoAmount)
{
if (CarriedAmmoMap.Contains(WeaponType))
@ -40,7 +48,7 @@ void UCombatComponent::PickupAmmo(EWeaponType WeaponType, int32 AmmoAmount)
CarriedAmmoMap[WeaponType] = FMath::Clamp(CarriedAmmoMap[WeaponType] + AmmoAmount, 0, MaxCarriedAmmo);
UpdateCarriedAmmo();
}
if (PrimaryWeapon && PrimaryWeapon->IsEmpty() && PrimaryWeapon->GetWeaponType() == WeaponType)
if (EquippedWeapon && EquippedWeapon->IsEmpty() && EquippedWeapon->GetWeaponType() == WeaponType)
{
Reload();
}
@ -84,29 +92,22 @@ void UCombatComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActo
void UCombatComponent::FireButtonPressed(bool bPressed)
{
bFireButtonPressed = bPressed;
if (bFireButtonPressed && PrimaryWeapon)
if (bFireButtonPressed)
{
Fire();
}
}
void UCombatComponent::ShotgunShellReload()
{
if (Character && Character->HasAuthority())
{
UpdateShotgunAmmoValues();
}
}
void UCombatComponent::Fire()
{
if (CanFire())
{
bCanFire = false;
if (PrimaryWeapon)
if (EquippedWeapon)
{
CrosshairShootingFactor = .75f;
switch (PrimaryWeapon->FireType)
switch (EquippedWeapon->FireType)
{
case EFireType::EFT_HitScan:
FireHitScanWeapon();
@ -125,52 +126,52 @@ void UCombatComponent::Fire()
void UCombatComponent::FireProjectileWeapon()
{
if (PrimaryWeapon && Character)
if (EquippedWeapon && Character)
{
HitTarget = PrimaryWeapon->bUseScatter ? PrimaryWeapon->TraceEndWithScatter(HitTarget) : HitTarget;
HitTarget = EquippedWeapon->bUseScatter ? EquippedWeapon->TraceEndWithScatter(HitTarget) : HitTarget;
if (!Character->HasAuthority()) LocalFire(HitTarget);
ServerFire(HitTarget, PrimaryWeapon->FireDelay);
ServerFire(HitTarget, EquippedWeapon->FireDelay);
}
}
void UCombatComponent::FireHitScanWeapon()
{
if (PrimaryWeapon && Character)
if (EquippedWeapon && Character)
{
HitTarget = PrimaryWeapon->bUseScatter ? PrimaryWeapon->TraceEndWithScatter(HitTarget) : HitTarget;
HitTarget = EquippedWeapon->bUseScatter ? EquippedWeapon->TraceEndWithScatter(HitTarget) : HitTarget;
if (!Character->HasAuthority()) LocalFire(HitTarget);
ServerFire(HitTarget, PrimaryWeapon->FireDelay);
ServerFire(HitTarget, EquippedWeapon->FireDelay);
}
}
void UCombatComponent::FireShotgun()
{
AShotgun* Shotgun = Cast<AShotgun>(PrimaryWeapon);
AShotgun* Shotgun = Cast<AShotgun>(EquippedWeapon);
if (Shotgun && Character)
{
TArray<FVector_NetQuantize> HitTargets;
Shotgun->ShotgunTraceEndWithScatter(HitTarget, HitTargets);
if (!Character->HasAuthority()) ShotgunLocalFire(HitTargets);
ServerShotgunFire(HitTargets, PrimaryWeapon->FireDelay);
ServerShotgunFire(HitTargets, EquippedWeapon->FireDelay);
}
}
void UCombatComponent::StartFireTimer()
{
if (PrimaryWeapon == nullptr || Character == nullptr) return;
if (EquippedWeapon == nullptr || Character == nullptr) return;
Character->GetWorldTimerManager().SetTimer(
FireTimer,
this,
&UCombatComponent::FireTimerFinished,
PrimaryWeapon->FireDelay
EquippedWeapon->FireDelay
);
}
void UCombatComponent::FireTimerFinished()
{
if (PrimaryWeapon == nullptr) return;
if (EquippedWeapon == nullptr) return;
bCanFire = true;
if (bFireButtonPressed && PrimaryWeapon->bAutomatic)
if (bFireButtonPressed && EquippedWeapon->bAutomatic)
{
Fire();
}
@ -184,8 +185,8 @@ void UCombatComponent::ServerFire_Implementation(const FVector_NetQuantize& Trac
bool UCombatComponent::ServerFire_Validate(const FVector_NetQuantize& TraceHitTarget, float FireDelay)
{
if (PrimaryWeapon == nullptr) return true;
return FMath::IsNearlyEqual(PrimaryWeapon->FireDelay, FireDelay, 0.001f);
if (EquippedWeapon == nullptr) return true;
return FMath::IsNearlyEqual(EquippedWeapon->FireDelay, FireDelay, 0.001f);
}
void UCombatComponent::MulticastFire_Implementation(const FVector_NetQuantize& TraceHitTarget)
@ -201,8 +202,8 @@ void UCombatComponent::ServerShotgunFire_Implementation(const TArray<FVector_Net
bool UCombatComponent::ServerShotgunFire_Validate(const TArray<FVector_NetQuantize>& TraceHitTargets, float FireDelay)
{
if (PrimaryWeapon == nullptr) return true;
return FMath::IsNearlyEqual(PrimaryWeapon->FireDelay, FireDelay, 0.001f);
if (EquippedWeapon == nullptr) return true;
return FMath::IsNearlyEqual(EquippedWeapon->FireDelay, FireDelay, 0.001f);
}
void UCombatComponent::MulticastShotgunFire_Implementation(const TArray<FVector_NetQuantize>& TraceHitTargets)
@ -213,20 +214,21 @@ void UCombatComponent::MulticastShotgunFire_Implementation(const TArray<FVector_
void UCombatComponent::LocalFire(const FVector_NetQuantize& TraceHitTarget)
{
if (PrimaryWeapon == nullptr) return;
if (EquippedWeapon == nullptr) return;
if (Character && CombatState == ECombatState::ECS_Unoccupied)
{
Character->PlayFireMontage(bAiming);
PrimaryWeapon->Fire(TraceHitTarget);
EquippedWeapon->Fire(TraceHitTarget);
}
}
void UCombatComponent::ShotgunLocalFire(const TArray<FVector_NetQuantize>& TraceHitTargets)
{
AShotgun* Shotgun = Cast<AShotgun>(PrimaryWeapon);
AShotgun* Shotgun = Cast<AShotgun>(EquippedWeapon);
if (Shotgun == nullptr || Character == nullptr) return;
if (CombatState == ECombatState::ECS_Reloading || CombatState == ECombatState::ECS_Unoccupied)
{
bLocallyReloading = false;
Character->PlayFireMontage(bAiming);
Shotgun->FireShotgun(TraceHitTargets);
CombatState = ECombatState::ECS_Unoccupied;
@ -238,7 +240,7 @@ void UCombatComponent::EquipWeapon(AWeapon* WeaponToEquip)
if (Character == nullptr || WeaponToEquip == nullptr) return;
if (CombatState != ECombatState::ECS_Unoccupied) return;
if (PrimaryWeapon != nullptr && SecondaryWeapon == nullptr)
if (EquippedWeapon != nullptr && SecondaryWeapon == nullptr)
{
EquipSecondaryWeapon(WeaponToEquip);
}
@ -262,23 +264,17 @@ void UCombatComponent::SwapWeapons()
if (SecondaryWeapon) SecondaryWeapon->EnableCustomDepth(false);
}
bool UCombatComponent::ShouldSwapWeapons()
{
return PrimaryWeapon != nullptr && SecondaryWeapon != nullptr;
}
void UCombatComponent::EquipPrimaryWeapon(AWeapon* WeaponToEquip)
{
if (WeaponToEquip == nullptr) return;
DropPrimaryWeapon();
PrimaryWeapon = WeaponToEquip;
PrimaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
AttachActorToRightHand(PrimaryWeapon);
PrimaryWeapon->SetOwner(Character);
PrimaryWeapon->SetHUDAmmo();
DropEquippedWeapon();
EquippedWeapon = WeaponToEquip;
EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
AttachActorToRightHand(EquippedWeapon);
EquippedWeapon->SetOwner(Character);
EquippedWeapon->SetHUDAmmo();
UpdateCarriedAmmo();
PlayEquipWeaponSound(PrimaryWeapon);
PlayEquipWeaponSound(WeaponToEquip);
ReloadEmptyWeapon();
}
@ -288,38 +284,23 @@ void UCombatComponent::EquipSecondaryWeapon(AWeapon* WeaponToEquip)
SecondaryWeapon = WeaponToEquip;
SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary);
AttachActorToBackpack(WeaponToEquip);
PlayEquipWeaponSound(SecondaryWeapon);
PlayEquipWeaponSound(WeaponToEquip);
SecondaryWeapon->SetOwner(Character);
}
void UCombatComponent::OnRep_PrimaryWeapon()
void UCombatComponent::OnRep_Aiming()
{
if (PrimaryWeapon && Character)
if (Character && Character->IsLocallyControlled())
{
PrimaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
AttachActorToRightHand(PrimaryWeapon);
Character->GetCharacterMovement()->bOrientRotationToMovement = false;
Character->bUseControllerRotationYaw = true;
PlayEquipWeaponSound(PrimaryWeapon);
PrimaryWeapon->SetHUDAmmo();
bAiming = bAimButtonPressed;
}
}
void UCombatComponent::OnRep_SecondaryWeapon()
void UCombatComponent::DropEquippedWeapon()
{
if (SecondaryWeapon && Character)
if (EquippedWeapon)
{
SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary);
AttachActorToBackpack(SecondaryWeapon);
PlayEquipWeaponSound(SecondaryWeapon);
}
}
void UCombatComponent::DropPrimaryWeapon()
{
if (PrimaryWeapon)
{
PrimaryWeapon->Dropped();
EquippedWeapon->Dropped();
}
}
@ -335,8 +316,8 @@ void UCombatComponent::AttachActorToRightHand(AActor* ActorToAttach)
void UCombatComponent::AttachActorToLeftHand(AActor* ActorToAttach)
{
if (Character == nullptr || Character->GetMesh() == nullptr || ActorToAttach == nullptr || PrimaryWeapon == nullptr) return;
bool bUsePistolSocket = PrimaryWeapon->IsPistol() || PrimaryWeapon->IsSMG();
if (Character == nullptr || Character->GetMesh() == nullptr || ActorToAttach == nullptr || EquippedWeapon == nullptr) return;
bool bUsePistolSocket = EquippedWeapon->IsPistol() || EquippedWeapon->IsSMG();
FName SocketName = bUsePistolSocket ? FName("LeftHandPistolSocket") : FName("LeftHandSocket");
const USkeletalMeshSocket* HandSocket = Character->GetMesh()->GetSocketByName(SocketName);
if (HandSocket)
@ -357,10 +338,10 @@ void UCombatComponent::AttachActorToBackpack(AActor* ActorToAttach)
void UCombatComponent::UpdateCarriedAmmo()
{
if (PrimaryWeapon == nullptr) return;
if (CarriedAmmoMap.Contains(PrimaryWeapon->GetWeaponType()))
if (EquippedWeapon == nullptr) return;
if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType()))
{
CarriedAmmo = CarriedAmmoMap[PrimaryWeapon->GetWeaponType()];
CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()];
}
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
@ -370,13 +351,13 @@ void UCombatComponent::UpdateCarriedAmmo()
}
}
void UCombatComponent::PlayEquipWeaponSound(const AWeapon* Weapon)
void UCombatComponent::PlayEquipWeaponSound(const AWeapon* WeaponToEquip)
{
if (Character && Weapon && Weapon->EquipSound)
if (Character && WeaponToEquip && WeaponToEquip->EquipSound)
{
UGameplayStatics::PlaySoundAtLocation(
this,
Weapon->EquipSound,
WeaponToEquip->EquipSound,
Character->GetActorLocation()
);
}
@ -384,7 +365,7 @@ void UCombatComponent::PlayEquipWeaponSound(const AWeapon* Weapon)
void UCombatComponent::ReloadEmptyWeapon()
{
if (PrimaryWeapon && PrimaryWeapon->IsEmpty())
if (EquippedWeapon && EquippedWeapon->IsEmpty())
{
Reload();
}
@ -392,7 +373,7 @@ void UCombatComponent::ReloadEmptyWeapon()
void UCombatComponent::Reload()
{
if (CarriedAmmo > 0 && CombatState == ECombatState::ECS_Unoccupied && PrimaryWeapon && !PrimaryWeapon->IsFull() && !bLocallyReloading)
if (CarriedAmmo > 0 && CombatState == ECombatState::ECS_Unoccupied && EquippedWeapon && !EquippedWeapon->IsFull() && !bLocallyReloading)
{
ServerReload();
HandleReload();
@ -402,10 +383,10 @@ void UCombatComponent::Reload()
void UCombatComponent::ServerReload_Implementation()
{
if (Character == nullptr || PrimaryWeapon == nullptr) return;
if (Character == nullptr || EquippedWeapon == nullptr) return;
// return if weapon mag is at max capacity
if (PrimaryWeapon->GetAmmo() == PrimaryWeapon->GetMagCapacity()) return;
if (EquippedWeapon->GetAmmo() == EquippedWeapon->GetMagCapacity()) return;
CombatState = ECombatState::ECS_Reloading;
if (!Character->IsLocallyControlled()) HandleReload();
@ -438,15 +419,17 @@ void UCombatComponent::FinishedSwap()
void UCombatComponent::FinishedSwapAttachWeapons()
{
AWeapon* TempWeapon = PrimaryWeapon;
PrimaryWeapon = SecondaryWeapon;
PlayEquipWeaponSound(SecondaryWeapon);
if (Character == nullptr || !Character->HasAuthority()) return;
AWeapon* TempWeapon = EquippedWeapon;
EquippedWeapon = SecondaryWeapon;
SecondaryWeapon = TempWeapon;
PrimaryWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
AttachActorToRightHand(PrimaryWeapon);
PrimaryWeapon->SetHUDAmmo();
EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
AttachActorToRightHand(EquippedWeapon);
EquippedWeapon->SetHUDAmmo();
UpdateCarriedAmmo();
PlayEquipWeaponSound(PrimaryWeapon);
SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary);
AttachActorToBackpack(SecondaryWeapon);
@ -454,49 +437,54 @@ void UCombatComponent::FinishedSwapAttachWeapons()
void UCombatComponent::DropWeapons()
{
if (PrimaryWeapon) PrimaryWeapon->Dropped();
if (EquippedWeapon) EquippedWeapon->Dropped();
if (SecondaryWeapon) SecondaryWeapon->Dropped();
}
void UCombatComponent::UpdateAmmoValues()
{
if (Character == nullptr || PrimaryWeapon == nullptr) return;
if (Character == nullptr || EquippedWeapon == nullptr) return;
int32 ReloadAmount = AmountToReload();
if (CarriedAmmoMap.Contains(PrimaryWeapon->GetWeaponType()))
if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType()))
{
CarriedAmmoMap[PrimaryWeapon->GetWeaponType()] -= ReloadAmount;
CarriedAmmo = CarriedAmmoMap[PrimaryWeapon->GetWeaponType()];
CarriedAmmoMap[EquippedWeapon->GetWeaponType()] -= ReloadAmount;
CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()];
}
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
if (Controller)
{
Controller->SetHUDCarriedAmmo(CarriedAmmo);
}
PrimaryWeapon->AddAmmo(ReloadAmount);
EquippedWeapon->AddAmmo(ReloadAmount);
}
void UCombatComponent::UpdateShotgunAmmoValues()
{
if (Character == nullptr || PrimaryWeapon == nullptr) return;
if (Character == nullptr || EquippedWeapon == nullptr) return;
if (CarriedAmmoMap.Contains(PrimaryWeapon->GetWeaponType()))
if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType()))
{
CarriedAmmoMap[PrimaryWeapon->GetWeaponType()] -= 1;
CarriedAmmo = CarriedAmmoMap[PrimaryWeapon->GetWeaponType()];
CarriedAmmoMap[EquippedWeapon->GetWeaponType()] -= 1;
CarriedAmmo = CarriedAmmoMap[EquippedWeapon->GetWeaponType()];
}
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
if (Controller)
{
Controller->SetHUDCarriedAmmo(CarriedAmmo);
}
PrimaryWeapon->AddAmmo(1);
EquippedWeapon->AddAmmo(1);
bCanFire = true;
if (PrimaryWeapon->IsFull() || CarriedAmmo == 0)
if (EquippedWeapon->IsFull() || CarriedAmmo == 0)
{
JumpToShotgunEnd();
}
}
void UCombatComponent::OnRep_Grenades()
{
UpdateHUDGrenades();
}
void UCombatComponent::JumpToShotgunEnd()
{
// Jump to ShotgunEnd section
@ -510,7 +498,7 @@ void UCombatComponent::JumpToShotgunEnd()
void UCombatComponent::ThrowGrenadeFinished()
{
CombatState = ECombatState::ECS_Unoccupied;
AttachActorToRightHand(PrimaryWeapon);
AttachActorToRightHand(EquippedWeapon);
}
void UCombatComponent::LaunchGrenade()
@ -531,7 +519,6 @@ void UCombatComponent::ServerLaunchGrenade_Implementation(const FVector_NetQuant
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = Character;
SpawnParams.Instigator = Character;
UWorld* World = GetWorld();
if (World)
{
@ -562,7 +549,7 @@ void UCombatComponent::OnRep_CombatState()
if (Character && !Character->IsLocallyControlled())
{
Character->PlayThrowGrenadeMontage();
AttachActorToLeftHand(PrimaryWeapon);
AttachActorToLeftHand(EquippedWeapon);
ShowAttachedGrenade(true);
}
break;
@ -585,12 +572,12 @@ void UCombatComponent::HandleReload()
int32 UCombatComponent::AmountToReload()
{
if (PrimaryWeapon == nullptr) return 0;
int32 RoomInMag = PrimaryWeapon->GetMagCapacity() - PrimaryWeapon->GetAmmo();
if (EquippedWeapon == nullptr) return 0;
int32 RoomInMag = EquippedWeapon->GetMagCapacity() - EquippedWeapon->GetAmmo();
if (CarriedAmmoMap.Contains(PrimaryWeapon->GetWeaponType()))
if (CarriedAmmoMap.Contains(EquippedWeapon->GetWeaponType()))
{
int32 AmountCarried = CarriedAmmoMap[PrimaryWeapon->GetWeaponType()];
int32 AmountCarried = CarriedAmmoMap[EquippedWeapon->GetWeaponType()];
int32 Least = FMath::Min(RoomInMag, AmountCarried);
return FMath::Clamp(RoomInMag, 0, Least);
}
@ -600,12 +587,12 @@ int32 UCombatComponent::AmountToReload()
void UCombatComponent::ThrowGrenade()
{
if (Grenades == 0) return;
if (CombatState != ECombatState::ECS_Unoccupied || PrimaryWeapon == nullptr) return;
if (CombatState != ECombatState::ECS_Unoccupied || EquippedWeapon == nullptr) return;
CombatState = ECombatState::ECS_ThrowingGrenade;
if (Character)
{
Character->PlayThrowGrenadeMontage();
AttachActorToLeftHand(PrimaryWeapon);
AttachActorToLeftHand(EquippedWeapon);
ShowAttachedGrenade(true);
}
if (Character && !Character->HasAuthority())
@ -626,27 +613,27 @@ void UCombatComponent::ServerThrowGrenade_Implementation()
if (Character)
{
Character->PlayThrowGrenadeMontage();
AttachActorToLeftHand(PrimaryWeapon);
AttachActorToLeftHand(EquippedWeapon);
ShowAttachedGrenade(true);
}
Grenades = FMath::Clamp(Grenades -1, 0, MaxGrenades);
UpdateHUDGrenades();
}
void UCombatComponent::OnRep_Grenades()
{
UpdateHUDGrenades();
}
void UCombatComponent::UpdateHUDGrenades()
{
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
Controller = Controller == nullptr ? Cast<ABlasterPlayerController>(Character->Controller) : Controller;
if (Controller)
{
Controller->SetHUDGrenades(Grenades);
}
}
bool UCombatComponent::ShouldSwapWeapons()
{
return EquippedWeapon != nullptr && SecondaryWeapon != nullptr;
}
void UCombatComponent::ShowAttachedGrenade(bool bShowGrenade)
{
if (Character && Character->GetAttachedGrenade())
@ -655,6 +642,30 @@ void UCombatComponent::ShowAttachedGrenade(bool bShowGrenade)
}
}
void UCombatComponent::OnRep_EquippedWeapon()
{
if (EquippedWeapon && Character)
{
EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
AttachActorToRightHand(EquippedWeapon);
Character->GetCharacterMovement()->bOrientRotationToMovement = false;
Character->bUseControllerRotationYaw = true;
PlayEquipWeaponSound(EquippedWeapon);
EquippedWeapon->EnableCustomDepth(false);
EquippedWeapon->SetHUDAmmo();
}
}
void UCombatComponent::OnRep_SecondaryWeapon()
{
if (SecondaryWeapon && Character)
{
SecondaryWeapon->SetWeaponState(EWeaponState::EWS_EquippedSecondary);
AttachActorToBackpack(SecondaryWeapon);
PlayEquipWeaponSound(EquippedWeapon);
}
}
void UCombatComponent::TraceUnderCrosshairs(FHitResult& TraceHitResult)
{
FVector2D ViewportSize;
@ -714,13 +725,13 @@ void UCombatComponent::SetHUDCrosshairs(float DeltaTime)
HUD = HUD == nullptr ? Cast<ABlasterHUD>(Controller->GetHUD()) : HUD;
if (HUD)
{
if (PrimaryWeapon)
if (EquippedWeapon)
{
HUDPackage.CrosshairsCenter = PrimaryWeapon->CrosshairsCenter;
HUDPackage.CrosshairsLeft = PrimaryWeapon->CrosshairsLeft;
HUDPackage.CrosshairsRight = PrimaryWeapon->CrosshairsRight;
HUDPackage.CrosshairsBottom = PrimaryWeapon->CrosshairsBottom;
HUDPackage.CrosshairsTop = PrimaryWeapon->CrosshairsTop;
HUDPackage.CrosshairsCenter = EquippedWeapon->CrosshairsCenter;
HUDPackage.CrosshairsLeft = EquippedWeapon->CrosshairsLeft;
HUDPackage.CrosshairsRight = EquippedWeapon->CrosshairsRight;
HUDPackage.CrosshairsBottom = EquippedWeapon->CrosshairsBottom;
HUDPackage.CrosshairsTop = EquippedWeapon->CrosshairsTop;
}
else
{
@ -774,11 +785,11 @@ void UCombatComponent::SetHUDCrosshairs(float DeltaTime)
void UCombatComponent::InterpFOV(float DeltaTime)
{
if (PrimaryWeapon == nullptr) return;
if (EquippedWeapon == nullptr) return;
if (bAiming)
{
CurrentFOV = FMath::FInterpTo(CurrentFOV, PrimaryWeapon->GetZoomedFOV(), DeltaTime, PrimaryWeapon->GetZoomInterpSpeed());
CurrentFOV = FMath::FInterpTo(CurrentFOV, EquippedWeapon->GetZoomedFOV(), DeltaTime, EquippedWeapon->GetZoomInterpSpeed());
}
else
{
@ -792,14 +803,14 @@ void UCombatComponent::InterpFOV(float DeltaTime)
void UCombatComponent::SetAiming(bool bIsAiming)
{
if (Character == nullptr || PrimaryWeapon == nullptr) return;
if (Character == nullptr || EquippedWeapon == nullptr) return;
bAiming = bIsAiming;
ServerSetAiming(bIsAiming);
if (Character)
{
Character->GetCharacterMovement()->MaxWalkSpeed = bIsAiming ? AimWalkSpeed : BaseWalkSpeed;
}
if (Character->IsLocallyControlled() && PrimaryWeapon->IsSniper())
if (Character->IsLocallyControlled() && EquippedWeapon->IsSniper())
{
Character->ShowSniperScopeWidget(bIsAiming);
}
@ -815,20 +826,12 @@ void UCombatComponent::ServerSetAiming_Implementation(bool bIsAiming)
}
}
void UCombatComponent::OnRep_Aiming()
{
if (Character && Character->IsLocallyControlled())
{
bAiming = bAimButtonPressed;
}
}
bool UCombatComponent::CanFire()
{
if (PrimaryWeapon == nullptr) return false;
if (PrimaryWeapon->IsEmpty()) return false;
if (EquippedWeapon == nullptr) return false;
if (EquippedWeapon->IsEmpty()) return false;
if (!bCanFire) return false;
if (CombatState == ECombatState::ECS_Reloading && PrimaryWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun) return true;
if (CombatState == ECombatState::ECS_Reloading && EquippedWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun) return true;
if (bLocallyReloading) return false;
return CombatState == ECombatState::ECS_Unoccupied;
}
@ -843,8 +846,8 @@ void UCombatComponent::OnRep_CarriedAmmo()
Controller->SetHUDCarriedAmmo(CarriedAmmo);
}
bool bJumpToShotgunEnd = CombatState == ECombatState::ECS_Reloading &&
PrimaryWeapon != nullptr &&
PrimaryWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun &&
EquippedWeapon != nullptr &&
EquippedWeapon->GetWeaponType() == EWeaponType::EWT_Shotgun &&
CarriedAmmo == 0;
if (bJumpToShotgunEnd)

View File

@ -62,7 +62,8 @@ protected:
void ServerSetAiming(bool bIsAiming);
UFUNCTION()
void OnRep_PrimaryWeapon();
void OnRep_EquippedWeapon();
UFUNCTION()
void OnRep_SecondaryWeapon();
@ -70,6 +71,8 @@ protected:
void FireProjectileWeapon();
void FireHitScanWeapon();
void FireShotgun();
void LocalFire(const FVector_NetQuantize& TraceHitTarget);
void ShotgunLocalFire(const TArray<FVector_NetQuantize>& TraceHitTargets);
UFUNCTION(Server, Reliable, WithValidation)
void ServerFire(const FVector_NetQuantize& TraceHitTarget, float FireDelay);
@ -101,12 +104,12 @@ protected:
UPROPERTY(EditAnywhere)
TSubclassOf<class AProjectile> GrenadeClass;
void DropPrimaryWeapon();
void DropEquippedWeapon();
void AttachActorToRightHand(AActor* ActorToAttach);
void AttachActorToLeftHand(AActor* ActorToAttach);
void AttachActorToBackpack(AActor* ActorToAttach);
void UpdateCarriedAmmo();
void PlayEquipWeaponSound(const AWeapon* Weapon);
void PlayEquipWeaponSound(const AWeapon* WeaponToEquip);
void ReloadEmptyWeapon();
void ShowAttachedGrenade(bool bShowGrenade);
void EquipPrimaryWeapon(AWeapon* WeaponToEquip);
@ -121,8 +124,8 @@ private:
UPROPERTY()
ABlasterHUD* HUD;
UPROPERTY(ReplicatedUsing=OnRep_PrimaryWeapon)
AWeapon* PrimaryWeapon;
UPROPERTY(ReplicatedUsing = OnRep_EquippedWeapon)
AWeapon* EquippedWeapon;
UPROPERTY(ReplicatedUsing = OnRep_SecondaryWeapon)
AWeapon* SecondaryWeapon;
@ -148,6 +151,9 @@ private:
float CrosshairInAirFactor;
float CrosshairAimFactor;
float CrosshairShootingFactor;
FVector HitTarget;
FHUDPackage HUDPackage;
// Aiming and FOV
@ -165,7 +171,6 @@ private:
void InterpFOV(float DeltaTime);
FVector HitTarget;
// Automatic fire
FTimerHandle FireTimer;
@ -173,8 +178,6 @@ private:
void StartFireTimer();
void FireTimerFinished();
void LocalFire(const FVector_NetQuantize& TraceHitTarget);
void ShotgunLocalFire(const TArray<FVector_NetQuantize>& TraceHitTargets);
bool CanFire();

View File

@ -13,110 +13,6 @@ ULagCompensationComponent::ULagCompensationComponent()
PrimaryComponentTick.bCanEverTick = true;
}
void ULagCompensationComponent::ServerScoreRequest_Implementation(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart,
const FVector_NetQuantize& HitLocation, float HitTime, AWeapon* DamageCauser)
{
const FServerSideRewindResult Confirm = ServerSideRewind(HitCharacter, TraceStart, HitLocation, HitTime);
if (Character && HitCharacter && DamageCauser && Confirm.bHitConfirmed)
{
UGameplayStatics::ApplyDamage(
HitCharacter,
DamageCauser->GetDamage(),
Character->Controller,
DamageCauser,
UDamageType::StaticClass()
);
}
}
void ULagCompensationComponent::ProjectileServerScoreRequest_Implementation(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart,
const FVector_NetQuantize100& InitialVelocity, float HitTime)
{
const FServerSideRewindResult Confirm = ProjectilServerSideRewind(HitCharacter, TraceStart, InitialVelocity, HitTime);
if (Character && HitCharacter && Confirm.bHitConfirmed)
{
UGameplayStatics::ApplyDamage(
HitCharacter,
Character->GetPrimaryWeapon()->GetDamage(),
Character->Controller,
Character->GetPrimaryWeapon(),
UDamageType::StaticClass()
);
}
}
void ULagCompensationComponent::ShotgunServerScoreRequest_Implementation(const TArray<ABlasterCharacter*>& HitCharacters, const FVector_NetQuantize& TraceStart,
const TArray<FVector_NetQuantize>& HitLocations, float HitTime)
{
FShotgunServerSideRewindResult Confirm = ShotgunServerSideRewind(HitCharacters, TraceStart, HitLocations, HitTime);
for (auto& HitCharacter : HitCharacters)
{
if (HitCharacter == nullptr || Character == nullptr || HitCharacter->GetPrimaryWeapon() == nullptr) continue;
float TotalDamage = 0.f;
if (Confirm.Headshots.Contains(HitCharacter))
{
TotalDamage += Confirm.Headshots[HitCharacter] * Character->GetPrimaryWeapon()->GetDamage();
}
if (Confirm.BodyShots.Contains(HitCharacter))
{
TotalDamage += Confirm.BodyShots[HitCharacter] * Character->GetPrimaryWeapon()->GetDamage();
}
UGameplayStatics::ApplyDamage(
HitCharacter,
TotalDamage,
Character->Controller,
Character->GetPrimaryWeapon(),
UDamageType::StaticClass()
);
}
}
void ULagCompensationComponent::SaveFramePackage()
{
if (Character == nullptr || !Character->HasAuthority()) return;
if (FrameHistory.Num() <= 1)
{
FFramePackage ThisFrame;
SaveFramePackage(ThisFrame);
FrameHistory.AddHead(ThisFrame);
}
else
{
float HistoryLength = FrameHistory.GetHead()->GetValue().Time - FrameHistory.GetTail()->GetValue().Time;
while (HistoryLength > MaxRecordTime)
{
FrameHistory.RemoveNode(FrameHistory.GetTail());
HistoryLength = FrameHistory.GetHead()->GetValue().Time - FrameHistory.GetTail()->GetValue().Time;
}
FFramePackage ThisFrame;
SaveFramePackage(ThisFrame);
FrameHistory.AddHead(ThisFrame);
}
}
void ULagCompensationComponent::SaveFramePackage(FFramePackage& Package)
{
Character = Character == nullptr ? Cast<ABlasterCharacter>(GetOwner()) : Character;
if (Character)
{
Package.Time = GetWorld()->GetTimeSeconds();
Package.Character = Character;
for (auto& BoxPair : Character->HitCollisionBoxes)
{
FBoxInformation BoxInformation;
BoxInformation.Location = BoxPair.Value->GetComponentLocation();
BoxInformation.Rotation = BoxPair.Value->GetComponentRotation();
BoxInformation.BoxExtend = BoxPair.Value->GetScaledBoxExtent();
Package.HitBoxInfo.Add(BoxPair.Key, BoxInformation);
}
}
}
FFramePackage ULagCompensationComponent::InterpBetweenFrames(const FFramePackage& OlderFrame, const FFramePackage& YoungerFrame, float HitTime)
{
const float Distance = YoungerFrame.Time - OlderFrame.Time;
@ -134,7 +30,7 @@ FFramePackage ULagCompensationComponent::InterpBetweenFrames(const FFramePackage
FBoxInformation InterpBoxInfo;
InterpBoxInfo.Location = FMath::VInterpTo(OlderBox.Location, YoungerBox.Location, 1.f, InterpFraction);
InterpBoxInfo.Rotation = FMath::RInterpTo(OlderBox.Rotation, YoungerBox.Rotation, 1.f, InterpFraction);
InterpBoxInfo.BoxExtend = OlderBox.BoxExtend;
InterpBoxInfo.BoxExtent = YoungerBox.BoxExtent;
InterpFramePackage.HitBoxInfo.Add(BoxInfoName, InterpBoxInfo);
}
@ -167,7 +63,6 @@ FServerSideRewindResult ULagCompensationComponent::ConfirmHit(const FFramePackag
TraceEnd,
ECC_HitBox
);
if (ConfirmHitResult.bBlockingHit) // we hit the head, return early
{
ResetHitBoxes(HitCharacter, CurrentFrame);
@ -377,7 +272,6 @@ FShotgunServerSideRewindResult ULagCompensationComponent::ShotgunConfirmHit(cons
void ULagCompensationComponent::CacheBoxPositions(ABlasterCharacter* HitCharacter, FFramePackage& OutFramePackage)
{
if (HitCharacter == nullptr) return;
for (auto& HitBoxPair : HitCharacter->HitCollisionBoxes)
{
if (HitBoxPair.Value != nullptr)
@ -385,8 +279,7 @@ void ULagCompensationComponent::CacheBoxPositions(ABlasterCharacter* HitCharacte
FBoxInformation BoxInfo;
BoxInfo.Location = HitBoxPair.Value->GetComponentLocation();
BoxInfo.Rotation = HitBoxPair.Value->GetComponentRotation();
BoxInfo.BoxExtend = HitBoxPair.Value->GetScaledBoxExtent();
BoxInfo.BoxExtent = HitBoxPair.Value->GetScaledBoxExtent();
OutFramePackage.HitBoxInfo.Add(HitBoxPair.Key, BoxInfo);
}
}
@ -395,14 +288,13 @@ void ULagCompensationComponent::CacheBoxPositions(ABlasterCharacter* HitCharacte
void ULagCompensationComponent::MoveBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package)
{
if (HitCharacter == nullptr) return;
for (auto& HitBoxPair : HitCharacter->HitCollisionBoxes)
{
if (HitBoxPair.Value != nullptr)
{
HitBoxPair.Value->SetWorldLocation(Package.HitBoxInfo[HitBoxPair.Key].Location);
HitBoxPair.Value->SetWorldRotation(Package.HitBoxInfo[HitBoxPair.Key].Rotation);
HitBoxPair.Value->SetBoxExtent(Package.HitBoxInfo[HitBoxPair.Key].BoxExtend);
HitBoxPair.Value->SetBoxExtent(Package.HitBoxInfo[HitBoxPair.Key].BoxExtent);
}
}
}
@ -410,14 +302,13 @@ void ULagCompensationComponent::MoveBoxes(ABlasterCharacter* HitCharacter, const
void ULagCompensationComponent::ResetHitBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package)
{
if (HitCharacter == nullptr) return;
for (auto& HitBoxPair : HitCharacter->HitCollisionBoxes)
{
if (HitBoxPair.Value != nullptr)
{
HitBoxPair.Value->SetWorldLocation(Package.HitBoxInfo[HitBoxPair.Key].Location);
HitBoxPair.Value->SetWorldRotation(Package.HitBoxInfo[HitBoxPair.Key].Rotation);
HitBoxPair.Value->SetBoxExtent(Package.HitBoxInfo[HitBoxPair.Key].BoxExtend);
HitBoxPair.Value->SetBoxExtent(Package.HitBoxInfo[HitBoxPair.Key].BoxExtent);
HitBoxPair.Value->SetCollisionEnabled(ECollisionEnabled::NoCollision);
}
}
@ -430,7 +321,7 @@ void ULagCompensationComponent::ShowFramePackage(const FFramePackage& Package, c
DrawDebugBox(
GetWorld(),
BoxInfo.Value.Location,
BoxInfo.Value.BoxExtend,
BoxInfo.Value.BoxExtent,
FQuat(BoxInfo.Value.Rotation),
Color,
false,
@ -446,7 +337,7 @@ FServerSideRewindResult ULagCompensationComponent::ServerSideRewind(ABlasterChar
return ConfirmHit(FrameToCheck, HitCharacter, TraceStart, HitLocation);
}
FServerSideRewindResult ULagCompensationComponent::ProjectilServerSideRewind(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart,
FServerSideRewindResult ULagCompensationComponent::ProjectileServerSideRewind(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart,
const FVector_NetQuantize100& InitialVelocity, float HitTime)
{
const FFramePackage FrameToCheck = GetFrameToCheck(HitCharacter, HitTime);
@ -471,9 +362,7 @@ FFramePackage ULagCompensationComponent::GetFrameToCheck(ABlasterCharacter* HitC
HitCharacter->GetLagCompensation() == nullptr ||
HitCharacter->GetLagCompensation()->FrameHistory.GetHead() == nullptr ||
HitCharacter->GetLagCompensation()->FrameHistory.GetTail() == nullptr;
if (bReturn) FFramePackage();
// Frame package that we check to verify a hit
FFramePackage FrameToCheck;
bool bShouldInterpolate = true;
@ -512,17 +401,76 @@ FFramePackage ULagCompensationComponent::GetFrameToCheck(ABlasterCharacter* HitC
FrameToCheck = Older->GetValue();
bShouldInterpolate = false;
}
if (bShouldInterpolate) // Why not just check if FrameToCheck == nullptr?
{
// Interpolate between Younger and Older
FrameToCheck = InterpBetweenFrames(Older->GetValue(), Younger->GetValue(), HitTime);
}
FrameToCheck.Character = HitCharacter;
return FrameToCheck;
}
void ULagCompensationComponent::ServerScoreRequest_Implementation(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart,
const FVector_NetQuantize& HitLocation, float HitTime, AWeapon* DamageCauser)
{
const FServerSideRewindResult Confirm = ServerSideRewind(HitCharacter, TraceStart, HitLocation, HitTime);
if (Character && HitCharacter && DamageCauser && Confirm.bHitConfirmed)
{
UGameplayStatics::ApplyDamage(
HitCharacter,
DamageCauser->GetDamage(),
Character->Controller,
DamageCauser,
UDamageType::StaticClass()
);
}
}
void ULagCompensationComponent::ProjectileServerScoreRequest_Implementation(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart,
const FVector_NetQuantize100& InitialVelocity, float HitTime)
{
const FServerSideRewindResult Confirm = ProjectileServerSideRewind(HitCharacter, TraceStart, InitialVelocity, HitTime);
if (Character && HitCharacter && Confirm.bHitConfirmed)
{
UGameplayStatics::ApplyDamage(
HitCharacter,
Character->GetPrimaryWeapon()->GetDamage(),
Character->Controller,
Character->GetPrimaryWeapon(),
UDamageType::StaticClass()
);
}
}
void ULagCompensationComponent::ShotgunServerScoreRequest_Implementation(const TArray<ABlasterCharacter*>& HitCharacters, const FVector_NetQuantize& TraceStart,
const TArray<FVector_NetQuantize>& HitLocations, float HitTime)
{
FShotgunServerSideRewindResult Confirm = ShotgunServerSideRewind(HitCharacters, TraceStart, HitLocations, HitTime);
for (auto& HitCharacter : HitCharacters)
{
if (HitCharacter == nullptr || Character == nullptr || HitCharacter->GetPrimaryWeapon() == nullptr) continue;
float TotalDamage = 0.f;
if (Confirm.Headshots.Contains(HitCharacter))
{
TotalDamage += Confirm.Headshots[HitCharacter] * Character->GetPrimaryWeapon()->GetDamage();
}
if (Confirm.BodyShots.Contains(HitCharacter))
{
TotalDamage += Confirm.BodyShots[HitCharacter] * Character->GetPrimaryWeapon()->GetDamage();
}
UGameplayStatics::ApplyDamage(
HitCharacter,
TotalDamage,
Character->Controller,
Character->GetPrimaryWeapon(),
UDamageType::StaticClass()
);
}
}
void ULagCompensationComponent::EnableCharacterMeshCollision(ABlasterCharacter* HitCharacter, ECollisionEnabled::Type CollisionEnabled)
{
@ -538,3 +486,44 @@ void ULagCompensationComponent::TickComponent(float DeltaTime, ELevelTick TickTy
SaveFramePackage();
}
void ULagCompensationComponent::SaveFramePackage()
{
if (Character == nullptr || !Character->HasAuthority()) return;
if (FrameHistory.Num() <= 1)
{
FFramePackage ThisFrame;
SaveFramePackage(ThisFrame);
FrameHistory.AddHead(ThisFrame);
}
else
{
float HistoryLength = FrameHistory.GetHead()->GetValue().Time - FrameHistory.GetTail()->GetValue().Time;
while (HistoryLength > MaxRecordTime)
{
FrameHistory.RemoveNode(FrameHistory.GetTail());
HistoryLength = FrameHistory.GetHead()->GetValue().Time - FrameHistory.GetTail()->GetValue().Time;
}
FFramePackage ThisFrame;
SaveFramePackage(ThisFrame);
FrameHistory.AddHead(ThisFrame);
}
}
void ULagCompensationComponent::SaveFramePackage(FFramePackage& Package)
{
Character = Character == nullptr ? Cast<ABlasterCharacter>(GetOwner()) : Character;
if (Character)
{
Package.Time = GetWorld()->GetTimeSeconds();
Package.Character = Character;
for (auto& BoxPair : Character->HitCollisionBoxes)
{
FBoxInformation BoxInformation;
BoxInformation.Location = BoxPair.Value->GetComponentLocation();
BoxInformation.Rotation = BoxPair.Value->GetComponentRotation();
BoxInformation.BoxExtent = BoxPair.Value->GetScaledBoxExtent();
Package.HitBoxInfo.Add(BoxPair.Key, BoxInformation);
}
}
}

View File

@ -19,7 +19,7 @@ struct FBoxInformation
FRotator Rotation;
UPROPERTY()
FVector BoxExtend;
FVector BoxExtent;
};
USTRUCT(BlueprintType)
@ -81,7 +81,7 @@ public:
);
// Projectiles
FServerSideRewindResult ProjectilServerSideRewind(
FServerSideRewindResult ProjectileServerSideRewind(
ABlasterCharacter* HitCharacter,
const FVector_NetQuantize& TraceStart,
const FVector_NetQuantize100& InitialVelocity,

View File

@ -88,9 +88,9 @@ void ABlasterGameMode::PlayerEliminated(class ABlasterCharacter* EliminatedChara
{
PlayersCurrentlyInTheLead.Add(LeadPlayer);
}
AttackerPlayerState->IncreaseScore(1.f);
BlasterGameState->UpdateTopScore(AttackerPlayerState);
if (BlasterGameState->TopScoringPlayers.Contains(AttackerPlayerState))
{
ABlasterCharacter* Leader = Cast<ABlasterCharacter>(AttackerPlayerState->GetPawn());
@ -99,6 +99,7 @@ void ABlasterGameMode::PlayerEliminated(class ABlasterCharacter* EliminatedChara
Leader->MulticastGainedTheLead();
}
}
for (int32 i = 0; i < PlayersCurrentlyInTheLead.Num(); i++)
{
if (!BlasterGameState->TopScoringPlayers.Contains(PlayersCurrentlyInTheLead[i]))

View File

@ -24,7 +24,7 @@ void ABlasterGameState::UpdateTopScore(ABlasterPlayerState* ScoringPlayer)
{
TopScoringPlayers.AddUnique(ScoringPlayer);
}
else if (ScoringPlayer->GetScore() < TopScore)
else if (ScoringPlayer->GetScore() > TopScore)
{
TopScoringPlayers.Empty();
TopScoringPlayers.AddUnique(ScoringPlayer);

View File

@ -28,15 +28,6 @@ void ABlasterPlayerController::BeginPlay()
ServerCheckMatchState();
}
void ABlasterPlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
if (InputComponent == nullptr) return;
InputComponent->BindAction("Quit", IE_Pressed, this, &ABlasterPlayerController::ShowReturnToMainMenu);
}
void ABlasterPlayerController::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
@ -72,11 +63,10 @@ void ABlasterPlayerController::Tick(float DeltaTime)
void ABlasterPlayerController::CheckPing(float DeltaTime)
{
if (HasAuthority()) return;
HighPingRunningTime += DeltaTime;
if (HighPingRunningTime > CheckPingFrequency)
{
HighPingRunningTime = 0.f;
PlayerState = PlayerState == nullptr ? GetPlayerState<APlayerState>() : PlayerState;
if (PlayerState)
{
@ -85,19 +75,18 @@ void ABlasterPlayerController::CheckPing(float DeltaTime)
HighPingWarning();
PingAnimationRunningTime = 0.f;
ServerReportPingStatus(true);
} else
}
else
{
ServerReportPingStatus(false);
}
}
HighPingRunningTime = 0.f;
}
bool bHighPingAnimationPlaying =
BlasterHUD &&
BlasterHUD->CharacterOverlay &&
BlasterHUD && BlasterHUD->CharacterOverlay &&
BlasterHUD->CharacterOverlay->HighPingAnimation &&
BlasterHUD->CharacterOverlay->IsAnimationPlaying(BlasterHUD->CharacterOverlay->HighPingAnimation);
if (bHighPingAnimationPlaying)
{
PingAnimationRunningTime += DeltaTime;
@ -108,6 +97,27 @@ void ABlasterPlayerController::CheckPing(float DeltaTime)
}
}
void ABlasterPlayerController::ShowReturnToMainMenu()
{
if (ReturnToMainMenuWidget == nullptr) return;
if (ReturnToMainMenu == nullptr)
{
ReturnToMainMenu = CreateWidget<UReturnToMainMenu>(this, ReturnToMainMenuWidget);
}
if (ReturnToMainMenu)
{
bReturnToMainMenuOpen = !bReturnToMainMenuOpen;
if (bReturnToMainMenuOpen)
{
ReturnToMainMenu->MenuSetup();
}
else
{
ReturnToMainMenu->MenuTearDown();
}
}
}
// Is the ping to high?
void ABlasterPlayerController::ServerReportPingStatus_Implementation(bool bHighPing)
{
@ -160,6 +170,37 @@ void ABlasterPlayerController::CheckTimeSync(float DeltaTime)
}
}
void ABlasterPlayerController::HighPingWarning()
{
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
bool bHUDValid = BlasterHUD &&
BlasterHUD->CharacterOverlay &&
BlasterHUD->CharacterOverlay->HighPingImage &&
BlasterHUD->CharacterOverlay->HighPingAnimation;
if (bHUDValid)
{
BlasterHUD->CharacterOverlay->HighPingImage->SetOpacity(1.f);
BlasterHUD->CharacterOverlay->PlayAnimation(BlasterHUD->CharacterOverlay->HighPingAnimation, 0.f, 5);
}
}
void ABlasterPlayerController::StopHighPingWarning()
{
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
bool bHUDValid = BlasterHUD &&
BlasterHUD->CharacterOverlay &&
BlasterHUD->CharacterOverlay->HighPingImage &&
BlasterHUD->CharacterOverlay->HighPingAnimation;
if (bHUDValid)
{
BlasterHUD->CharacterOverlay->HighPingImage->SetOpacity(0.f);
if (BlasterHUD->CharacterOverlay->IsAnimationPlaying(BlasterHUD->CharacterOverlay->HighPingAnimation))
{
BlasterHUD->CharacterOverlay->StopAnimation(BlasterHUD->CharacterOverlay->HighPingAnimation);
}
}
}
void ABlasterPlayerController::ServerCheckMatchState_Implementation()
{
ABlasterGameMode* GameMode = Cast<ABlasterGameMode>(UGameplayStatics::GetGameMode(this));
@ -292,7 +333,7 @@ void ABlasterPlayerController::SetHUDWeaponAmmo(int32 Ammo)
}
else
{
bInitializeHUDWeaponAmmo = true;
bInitializeWeaponAmmo = true;
HUDWeaponAmmo = Ammo;
}
}
@ -315,24 +356,6 @@ void ABlasterPlayerController::SetHUDCarriedAmmo(int32 Ammo)
}
}
void ABlasterPlayerController::SetHUDGrenades(int32 Grenades)
{
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
bool bHUDValid = BlasterHUD &&
BlasterHUD->CharacterOverlay &&
BlasterHUD->CharacterOverlay->GrenadesAmount;
if (bHUDValid)
{
FString GrenadesText = FString::Printf(TEXT("%d"), Grenades);
BlasterHUD->CharacterOverlay->GrenadesAmount->SetText(FText::FromString(GrenadesText));
}
else
{
bInitializeGrenades = true;
HUDGrenades = Grenades;
}
}
void ABlasterPlayerController::SetHUDMatchCountdown(float CountdownTime)
{
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
@ -377,24 +400,31 @@ void ABlasterPlayerController::SetHUDAnnouncementCountdown(float CountdownTime)
}
}
void ABlasterPlayerController::SetHUDGrenades(int32 Grenades)
{
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
bool bHUDValid = BlasterHUD &&
BlasterHUD->CharacterOverlay &&
BlasterHUD->CharacterOverlay->GrenadesAmount;
if (bHUDValid)
{
FString GrenadesText = FString::Printf(TEXT("%d"), Grenades);
BlasterHUD->CharacterOverlay->GrenadesAmount->SetText(FText::FromString(GrenadesText));
}
else
{
bInitializeGrenades = true;
HUDGrenades = Grenades;
}
}
void ABlasterPlayerController::SetHUDTime()
{
float TimeLeft = 0.f;
if (MatchState == MatchState::WaitingToStart) TimeLeft = WarmupTime - GetServerTime(); // + LevelStartingTime;
else if (MatchState == MatchState::InProgress) TimeLeft = WarmupTime + MatchTime - GetServerTime(); // + LevelStartingTime;
else if (MatchState == MatchState::Cooldown) TimeLeft = WarmupTime + MatchTime + CooldownTime - GetServerTime(); // + LevelStartingTime;
uint32 SecondsLeft = FMath::CeilToInt(TimeLeft);
if (HasAuthority())
{
BlasterGameMode = BlasterGameMode == nullptr ? Cast<ABlasterGameMode>(UGameplayStatics::GetGameMode(this)) : BlasterGameMode;
if (BlasterGameMode)
{
SecondsLeft = FMath::CeilToInt(BlasterGameMode->GetCountdownTime());
}
}
if (CountdownInt != SecondsLeft)
{
if (MatchState == MatchState::WaitingToStart || MatchState == MatchState::Cooldown)
@ -435,7 +465,8 @@ void ABlasterPlayerController::PollInit()
if (bInitializeScore) SetHUDScore(HUDScore);
if (bInitializeDefeats) SetHUDDefeats(HUDDefeats);
if (bInitializeCarriedAmmo) SetHUDCarriedAmmo(HUDCarriedAmmo);
if (bInitializeHUDWeaponAmmo) SetHUDWeaponAmmo(HUDWeaponAmmo);
if (bInitializeWeaponAmmo) SetHUDWeaponAmmo(HUDWeaponAmmo);
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(GetPawn());
if (BlasterCharacter && BlasterCharacter->GetCombat())
{
@ -446,57 +477,13 @@ void ABlasterPlayerController::PollInit()
}
}
void ABlasterPlayerController::HighPingWarning()
void ABlasterPlayerController::SetupInputComponent()
{
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
bool bHUDValid = BlasterHUD &&
BlasterHUD->CharacterOverlay &&
BlasterHUD->CharacterOverlay->HighPingImage &&
BlasterHUD->CharacterOverlay->HighPingAnimation;
if (bHUDValid)
{
BlasterHUD->CharacterOverlay->HighPingImage->SetOpacity(1.f);
BlasterHUD->CharacterOverlay->PlayAnimation(BlasterHUD->CharacterOverlay->HighPingAnimation, 0.f, 5);
}
}
Super::SetupInputComponent();
if (InputComponent == nullptr) return;
void ABlasterPlayerController::StopHighPingWarning()
{
BlasterHUD = BlasterHUD == nullptr ? Cast<ABlasterHUD>(GetHUD()) : BlasterHUD;
bool bHUDValid = BlasterHUD &&
BlasterHUD->CharacterOverlay &&
BlasterHUD->CharacterOverlay->HighPingImage &&
BlasterHUD->CharacterOverlay->HighPingAnimation;
if (bHUDValid)
{
BlasterHUD->CharacterOverlay->HighPingImage->SetOpacity(0.f);
if (BlasterHUD->CharacterOverlay->IsAnimationPlaying(BlasterHUD->CharacterOverlay->HighPingAnimation))
{
BlasterHUD->CharacterOverlay->StopAnimation(BlasterHUD->CharacterOverlay->HighPingAnimation);
}
}
}
InputComponent->BindAction("Quit", IE_Pressed, this, &ABlasterPlayerController::ShowReturnToMainMenu);
void ABlasterPlayerController::ShowReturnToMainMenu()
{
if (ReturnToMainMenuWidget == nullptr) return;
if (ReturnToMainMenu == nullptr)
{
ReturnToMainMenu = CreateWidget<UReturnToMainMenu>(this, ReturnToMainMenuWidget);
}
if (ReturnToMainMenu)
{
bReturnToMainMenuOpen = !bReturnToMainMenuOpen;
if (bReturnToMainMenuOpen)
{
ReturnToMainMenu->MenuSetup();
}
else
{
ReturnToMainMenu->MenuTearDown();
}
}
}
void ABlasterPlayerController::ServerRequestServerTime_Implementation(float TimeOfClientRequest)

View File

@ -143,7 +143,7 @@ private:
float bInitializeCarriedAmmo = false;
float HUDCarriedAmmo;
float bInitializeHUDWeaponAmmo = false;
float bInitializeWeaponAmmo = false;
float HUDWeaponAmmo;
// High Ping Indicator

View File

@ -51,42 +51,6 @@ void AProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimi
Destroy();
}
void AProjectile::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AProjectile::StartDestroyTimer()
{
GetWorldTimerManager().SetTimer(
DestroyTimer,
this,
&AProjectile::DestroyTimerFinished,
DestroyTime
);
}
void AProjectile::DestroyTimerFinished()
{
Destroy();
}
void AProjectile::Destroyed()
{
Super::Destroyed();
if (ImpactParticles)
{
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ImpactParticles, GetActorTransform());
}
if (ImpactSound)
{
UGameplayStatics::PlaySoundAtLocation(this, ImpactSound, GetActorLocation());
}
}
void AProjectile::SpawnTrailSystem()
{
if (TrailSystem)
@ -127,3 +91,37 @@ void AProjectile::ExplodeDamage()
}
}
}
void AProjectile::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AProjectile::StartDestroyTimer()
{
GetWorldTimerManager().SetTimer(
DestroyTimer,
this,
&AProjectile::DestroyTimerFinished,
DestroyTime
);
}
void AProjectile::DestroyTimerFinished()
{
Destroy();
}
void AProjectile::Destroyed()
{
Super::Destroyed();
if (ImpactParticles)
{
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ImpactParticles, GetActorTransform());
}
if (ImpactSound)
{
UGameplayStatics::PlaySoundAtLocation(this, ImpactSound, GetActorLocation());
}
}

View File

@ -86,6 +86,7 @@ void AProjectileBullet::BeginPlay()
PathParams.ActorsToIgnore.Add(this);
FPredictProjectilePathResult PathResult;
UGameplayStatics::PredictProjectilePath(this, PathParams, PathResult);
*/
}

View File

@ -26,30 +26,12 @@ void AProjectileGrenade::BeginPlay()
SpawnTrailSystem();
StartDestroyTimer();
ProjectileMovementComponent->OnProjectileBounce.AddDynamic(this, &AProjectileGrenade::OnBounce);
}
void AProjectileGrenade::OnBounce(const FHitResult& ImpactResult, const FVector& ImpactVelocity)
{
if (ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(ImpactResult.GetActor()))
{
const APawn* FiringPawn = GetInstigator();
if (FiringPawn && HasAuthority())
{
AController* InstigatorController = FiringPawn->GetController();
if (InstigatorController)
{
UGameplayStatics::ApplyDamage(
BlasterCharacter,
Damage / 4,
InstigatorController,
this,
UDamageType::StaticClass()
);
}
}
}
if (BounceSound)
{
UGameplayStatics::PlaySoundAtLocation(

View File

@ -16,7 +16,7 @@ AProjectileRocket::AProjectileRocket()
ProjectileMesh->SetupAttachment(RootComponent);
ProjectileMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
RocketMovementComponent = CreateDefaultSubobject<URocketMovementComponent>("RocketMovementComponent");
RocketMovementComponent = CreateDefaultSubobject<URocketMovementComponent>(TEXT("RocketMovementComponent"));
RocketMovementComponent->bRotationFollowsVelocity = true;
RocketMovementComponent->SetIsReplicated(true);
}

View File

@ -49,7 +49,6 @@ void AProjectileWeapon::Fire(const FVector& HitTarget)
SpawnedProjectile->bUseServerSideRewind = true;
SpawnedProjectile->TraceStart = SocketTransform.GetLocation();
SpawnedProjectile->InitialVelocity = SpawnedProjectile->GetActorForwardVector() * SpawnedProjectile->InitialSpeed;
SpawnedProjectile->Damage = Damage;
}
else // Client, not locally controlled - spawn non-replicated projectile, no SSR
{

View File

@ -3,11 +3,10 @@
#include "RocketMovementComponent.h"
UProjectileMovementComponent::EHandleBlockingHitResult URocketMovementComponent::HandleBlockingHit(const FHitResult& Hit, float TimeTick,
URocketMovementComponent::EHandleBlockingHitResult URocketMovementComponent::HandleBlockingHit(const FHitResult& Hit, float TimeTick,
const FVector& MoveDelta, float& SubTickTimeRemaining)
{
Super::HandleBlockingHit(Hit, TimeTick, MoveDelta, SubTickTimeRemaining);
return EHandleBlockingHitResult::AdvanceNextSubstep;
}

View File

@ -114,7 +114,6 @@ void AShotgun::ShotgunTraceEndWithScatter(const FVector& HitTarget, TArray<FVect
const FVector ToTargetNormalized = (HitTarget - TraceStart).GetSafeNormal();
const FVector SphereCenter = TraceStart + ToTargetNormalized * DistanceToSphere;
for (uint32 i = 0; i < NumberOfPellets; i++)
{
const FVector RandVec = UKismetMathLibrary::RandomUnitVector() * FMath::FRandRange(0.f, SphereRadius);

View File

@ -95,25 +95,6 @@ void AWeapon::OnSphereEndOverlap(UPrimitiveComponent* OverlappedComponent, AActo
}
}
void AWeapon::OnRep_Owner()
{
Super::OnRep_Owner();
if (Owner == nullptr)
{
OwnerCharacter = nullptr;
OwnerController = nullptr;
}
else
{
OwnerCharacter = OwnerCharacter == nullptr ? Cast<ABlasterCharacter>(Owner) : OwnerCharacter;
if (OwnerCharacter && OwnerCharacter->GetPrimaryWeapon() && OwnerCharacter->GetPrimaryWeapon() == this)
{
SetHUDAmmo();
}
}
}
void AWeapon::SetHUDAmmo()
{
OwnerCharacter = OwnerCharacter == nullptr ? Cast<ABlasterCharacter>(GetOwner()) : OwnerCharacter;
@ -169,6 +150,24 @@ void AWeapon::ClientAddAmmo_Implementation(int32 AmmoToAdd)
SetHUDAmmo();
}
void AWeapon::OnRep_Owner()
{
Super::OnRep_Owner();
if (Owner == nullptr)
{
OwnerCharacter = nullptr;
OwnerController = nullptr;
}
else
{
OwnerCharacter = OwnerCharacter == nullptr ? Cast<ABlasterCharacter>(Owner) : OwnerCharacter;
if (OwnerCharacter && OwnerCharacter->GetPrimaryWeapon() && OwnerCharacter->GetPrimaryWeapon() == this)
{
SetHUDAmmo();
}
}
}
void AWeapon::SetWeaponState(EWeaponState State)
{
WeaponState = State;
@ -204,7 +203,7 @@ void AWeapon::OnRep_WeaponState()
void AWeapon::OnEquipped()
{
ShowPickupWidget(false);
GetAreaSphere()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
AreaSphere->SetCollisionEnabled(ECollisionEnabled::NoCollision);
WeaponMesh->SetSimulatePhysics(false);
WeaponMesh->SetEnableGravity(false);
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
@ -227,10 +226,37 @@ void AWeapon::OnEquipped()
}
}
void AWeapon::OnDropped()
{
if (HasAuthority())
{
AreaSphere->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
}
WeaponMesh->SetSimulatePhysics(true);
WeaponMesh->SetEnableGravity(true);
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
WeaponMesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
WeaponMesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Ignore);
WeaponMesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Ignore);
WeaponMesh->SetCustomDepthStencilValue(CUSTOM_DEPTH_BLUE);
WeaponMesh->MarkRenderStateDirty();
EnableCustomDepth(true);
OwnerCharacter = OwnerCharacter == nullptr ? Cast<ABlasterCharacter>(GetOwner()) : OwnerCharacter;
if (OwnerCharacter && bUseServerSideRewind)
{
OwnerController = OwnerController == nullptr ? Cast<ABlasterPlayerController>(OwnerCharacter->Controller) : OwnerController;
if (OwnerController && HasAuthority() && OwnerController->HighPingDelegate.IsBound())
{
OwnerController->HighPingDelegate.RemoveDynamic(this, &AWeapon::OnPingTooHigh);
}
}
}
void AWeapon::OnEquippedSecondary()
{
ShowPickupWidget(false);
GetAreaSphere()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
AreaSphere->SetCollisionEnabled(ECollisionEnabled::NoCollision);
WeaponMesh->SetSimulatePhysics(false);
WeaponMesh->SetEnableGravity(false);
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
@ -256,35 +282,6 @@ void AWeapon::OnEquippedSecondary()
}
}
void AWeapon::OnDropped()
{
if (HasAuthority())
{
GetAreaSphere()->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
}
WeaponMesh->SetSimulatePhysics(true);
WeaponMesh->SetEnableGravity(true);
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
WeaponMesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
WeaponMesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Ignore);
WeaponMesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Ignore);
WeaponMesh->SetCustomDepthStencilValue(CUSTOM_DEPTH_BLUE);
WeaponMesh->MarkRenderStateDirty();
EnableCustomDepth(true);
OwnerCharacter = OwnerCharacter == nullptr ? Cast<ABlasterCharacter>(GetOwner()) : OwnerCharacter;
if (OwnerCharacter && bUseServerSideRewind)
{
OwnerController = OwnerController == nullptr ? Cast<ABlasterPlayerController>(OwnerCharacter->Controller) : OwnerController;
if (OwnerController && HasAuthority() && OwnerController->HighPingDelegate.IsBound())
{
OwnerController->HighPingDelegate.RemoveDynamic(this, &AWeapon::OnPingTooHigh);
}
}
}
bool AWeapon::IsEmpty()
{
return Ammo <= 0;