blaster/Source/Blaster/Components/CombatComponent.cpp

146 lines
3.6 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "CombatComponent.h"
#include "Blaster/Character/BlasterCharacter.h"
#include "Blaster/Weapon/Weapon.h"
#include "Engine/SkeletalMeshSocket.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Kismet/GameplayStatics.h"
#include "Net/UnrealNetwork.h"
UCombatComponent::UCombatComponent()
{
PrimaryComponentTick.bCanEverTick = true;
BaseWalkSpeed = 600.f;
AimWalkSpeed = 350.f;
}
void UCombatComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(UCombatComponent, EquippedWeapon);
DOREPLIFETIME(UCombatComponent, bAiming);
}
void UCombatComponent::BeginPlay()
{
Super::BeginPlay();
if (Character)
{
Character->GetCharacterMovement()->MaxWalkSpeed = BaseWalkSpeed;
}
}
void UCombatComponent::SetAiming(bool bIsAiming)
{
bAiming = bIsAiming;
ServerSetAiming(bIsAiming);
if (Character)
{
Character->GetCharacterMovement()->MaxWalkSpeed = bIsAiming ? AimWalkSpeed : BaseWalkSpeed;
}
}
void UCombatComponent::ServerSetAiming_Implementation(bool bIsAiming)
{
bAiming = bIsAiming;
if (Character)
{
Character->GetCharacterMovement()->MaxWalkSpeed = bIsAiming ? AimWalkSpeed : BaseWalkSpeed;
}
}
void UCombatComponent::OnRep_EquippedWeapon()
{
if (EquippedWeapon && Character)
{
Character->GetCharacterMovement()->bOrientRotationToMovement = false;
Character->bUseControllerRotationYaw = true;
}
}
void UCombatComponent::FireButtonPressed(bool bPressed)
{
bFireButtonPressed = bPressed;
if (bFireButtonPressed)
{
FHitResult HitResult;
TraceUnderCrosshairs(HitResult);
ServerFire(HitResult.ImpactPoint);
}
}
void UCombatComponent::TraceUnderCrosshairs(FHitResult& TraceHitResult)
{
FVector2d ViewPortSize;
if (GEngine && GEngine->GameViewport)
{
GEngine->GameViewport->GetViewportSize(ViewPortSize);
}
FVector2d CrosshairLocation(ViewPortSize.X / 2.f, ViewPortSize.Y / 2.0f);
FVector CrosshairWorldPosition;
FVector CrosshairWorldDirection;
bool bScreenToWorld = UGameplayStatics::DeprojectScreenToWorld(
UGameplayStatics::GetPlayerController(this, 0),
CrosshairLocation,
CrosshairWorldPosition,
CrosshairWorldDirection
);
if (bScreenToWorld)
{
FVector Start = CrosshairWorldPosition;
FVector End = Start + CrosshairWorldDirection * TRACE_LENGTH;
GetWorld()->LineTraceSingleByChannel(
TraceHitResult,
Start,
End,
ECollisionChannel::ECC_Visibility
);
}
}
void UCombatComponent::ServerFire_Implementation(const FVector_NetQuantize& TraceHitTarget)
{
MulticastFire(TraceHitTarget);
}
void UCombatComponent::MulticastFire_Implementation(const FVector_NetQuantize& TraceHitTarget)
{
if (EquippedWeapon == nullptr) return;
if (Character)
{
Character->PlayFireMontage(bAiming);
EquippedWeapon->Fire(TraceHitTarget);
}
}
void UCombatComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}
void UCombatComponent::EquipWeapon(AWeapon* WeaponToEquip)
{
if (Character == nullptr || WeaponToEquip == nullptr) return;
EquippedWeapon = WeaponToEquip;
EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
const USkeletalMeshSocket* HandSocket = Character->GetMesh()->GetSocketByName(FName("RightHandSocket"));
if (HandSocket)
{
HandSocket->AttachActor(EquippedWeapon, Character->GetMesh());
}
EquippedWeapon->SetOwner(Character);
Character->GetCharacterMovement()->bOrientRotationToMovement = false;
Character->bUseControllerRotationYaw = true;
}