blaster/Source/Blaster/Weapon/Weapon.cpp

167 lines
4.6 KiB
C++
Raw Normal View History

2022-04-29 22:26:35 +00:00
// Fill out your copyright notice in the Description page of Project Settings.
#include "Weapon.h"
2022-05-05 13:49:24 +00:00
#include "Casing.h"
2022-04-29 23:19:55 +00:00
#include "Blaster/Character/BlasterCharacter.h"
2022-04-29 22:26:35 +00:00
#include "Components/SphereComponent.h"
2022-04-29 23:19:55 +00:00
#include "Components/WidgetComponent.h"
2022-05-05 13:49:24 +00:00
#include "Engine/SkeletalMeshSocket.h"
2022-04-30 14:08:00 +00:00
#include "Net/UnrealNetwork.h"
2022-04-29 22:26:35 +00:00
AWeapon::AWeapon()
{
PrimaryActorTick.bCanEverTick = false;
bReplicates = true;
2022-04-29 23:19:55 +00:00
2022-04-29 22:26:35 +00:00
WeaponMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("WeaponMesh"));
2022-04-29 23:19:55 +00:00
SetRootComponent(WeaponMesh);
2022-04-29 22:26:35 +00:00
WeaponMesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
WeaponMesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Ignore);
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
AreaSphere = CreateDefaultSubobject<USphereComponent>(TEXT("AreaSphere"));
AreaSphere->SetupAttachment(RootComponent);
AreaSphere->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
AreaSphere->SetCollisionEnabled(ECollisionEnabled::NoCollision);
2022-04-29 23:19:55 +00:00
PickupWidget = CreateDefaultSubobject<UWidgetComponent>(TEXT("PickupWidget"));
PickupWidget->SetupAttachment(RootComponent);
2022-04-29 22:26:35 +00:00
}
2022-04-30 14:08:00 +00:00
void AWeapon::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AWeapon, WeaponState);
}
2022-04-29 22:26:35 +00:00
void AWeapon::BeginPlay()
{
Super::BeginPlay();
if (HasAuthority())
{
AreaSphere->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
AreaSphere->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Overlap);
2022-04-29 23:19:55 +00:00
AreaSphere->OnComponentBeginOverlap.AddDynamic(this, &AWeapon::OnSphereOverlap);
2022-04-30 10:26:25 +00:00
AreaSphere->OnComponentEndOverlap.AddDynamic(this, &AWeapon::OnSphereEndOverlap);
2022-04-29 22:26:35 +00:00
}
2022-04-29 23:19:55 +00:00
if (PickupWidget)
{
PickupWidget->SetVisibility(false);
}
}
2022-04-29 22:26:35 +00:00
2022-04-29 23:19:55 +00:00
void AWeapon::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent,
AActor* OtherActor,
UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex,
bool bFromSweep,
const FHitResult& SweepResult)
{
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(OtherActor);
2022-04-30 10:26:25 +00:00
if (BlasterCharacter)
2022-04-29 23:19:55 +00:00
{
2022-04-30 10:26:25 +00:00
BlasterCharacter->SetOverlappingWeapon(this);
}
}
void AWeapon::OnSphereEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
2022-04-30 14:08:00 +00:00
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
2022-04-30 10:26:25 +00:00
{
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(OtherActor);
if (BlasterCharacter)
{
BlasterCharacter->SetOverlappingWeapon(nullptr);
}
}
2022-04-30 14:08:00 +00:00
void AWeapon::SetWeaponState(EWeaponState State)
{
WeaponState = State;
switch (WeaponState)
{
case EWeaponState::EWS_Equipped:
ShowPickupWidget(false);
GetAreaSphere()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
2022-05-08 17:31:58 +00:00
WeaponMesh->SetSimulatePhysics(false);
WeaponMesh->SetEnableGravity(false);
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
break;
case EWeaponState::EWS_Dropped:
if (HasAuthority())
{
GetAreaSphere()->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
}
WeaponMesh->SetSimulatePhysics(true);
WeaponMesh->SetEnableGravity(true);
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
2022-04-30 14:08:00 +00:00
break;
}
}
void AWeapon::OnRep_WeaponState()
{
switch (WeaponState)
{
case EWeaponState::EWS_Equipped:
ShowPickupWidget(false);
2022-05-08 17:31:58 +00:00
WeaponMesh->SetSimulatePhysics(false);
WeaponMesh->SetEnableGravity(false);
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
break;
case EWeaponState::EWS_Dropped:
WeaponMesh->SetSimulatePhysics(true);
WeaponMesh->SetEnableGravity(true);
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
2022-04-30 14:08:00 +00:00
break;
}
}
2022-04-30 10:26:25 +00:00
void AWeapon::ShowPickupWidget(bool bShowWidget)
{
if (PickupWidget)
{
PickupWidget->SetVisibility(bShowWidget);
2022-04-29 23:19:55 +00:00
}
}
2022-05-04 20:27:26 +00:00
2022-05-05 10:51:14 +00:00
void AWeapon::Fire(const FVector& HitTarget)
2022-05-04 20:27:26 +00:00
{
if (FireAnimation)
{
WeaponMesh->PlayAnimation(FireAnimation, false);
}
2022-05-05 13:49:24 +00:00
if (CasingClass)
{
const USkeletalMeshSocket* AmmoEjectSocket = WeaponMesh->GetSocketByName(FName("AmmoEject"));
if (AmmoEjectSocket)
{
FTransform SocketTransform = AmmoEjectSocket->GetSocketTransform(WeaponMesh);
UWorld* World = GetWorld();
if (World)
{
World->SpawnActor<ACasing>(
CasingClass,
SocketTransform.GetLocation(),
SocketTransform.GetRotation().Rotator()
);
}
}
}
2022-05-04 20:27:26 +00:00
}
2022-05-08 17:31:58 +00:00
void AWeapon::Dropped()
{
SetWeaponState(EWeaponState::EWS_Dropped);
const FDetachmentTransformRules DetachRules(EDetachmentRule::KeepWorld, true);
WeaponMesh->DetachFromComponent(DetachRules);
SetOwner(nullptr);
}