199 lines
5.5 KiB
C++
199 lines
5.5 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
|
|
#include "Weapon.h"
|
|
|
|
AWeapon::AWeapon() :
|
|
ThrowWeaponTime(0.7f),
|
|
bFalling(false),
|
|
Ammo(30),
|
|
MagazineCapacity(30),
|
|
WeaponType(EWeaponType::EWT_SubmachineGun),
|
|
AmmoType(EAmmoType::EAT_9mm),
|
|
ReloadMontageSection(FName(TEXT("Reload SMG"))),
|
|
ClipBoneName(TEXT("smg_clip")),
|
|
SlideDisplacement(0.f),
|
|
SlideDisplacementTime(0.2f),
|
|
bMovingSlide(false),
|
|
MaxSlideDisplacement(4.f),
|
|
MaxRecoilRotation(20.f),
|
|
bAutomatic(true)
|
|
{
|
|
PrimaryActorTick.bCanEverTick = true;
|
|
}
|
|
|
|
void AWeapon::Tick(float DeltaTime)
|
|
{
|
|
Super::Tick(DeltaTime);
|
|
|
|
/* Keep it upright */
|
|
if (GetItemState() == EItemState::EIS_Falling && bFalling)
|
|
{
|
|
FRotator MeshRotation{ 0.f, GetItemMesh()->GetComponentRotation().Yaw, 0.f };
|
|
GetItemMesh()->SetWorldRotation(MeshRotation, false,
|
|
nullptr, ETeleportType::TeleportPhysics);
|
|
}
|
|
|
|
// Update slide on pistol
|
|
UpdateSlideDisplacement();
|
|
}
|
|
|
|
void AWeapon::ThrowWeapon()
|
|
{
|
|
FRotator MeshRotation{ 0.f, GetItemMesh()->GetComponentRotation().Yaw, 0.f };
|
|
GetItemMesh()->SetWorldRotation(MeshRotation, false,
|
|
nullptr, ETeleportType::TeleportPhysics);
|
|
|
|
const FVector MeshForward{ GetItemMesh()->GetForwardVector() };
|
|
const FVector MeshRight{ GetItemMesh()->GetRightVector() };
|
|
|
|
// Direction in which we throw the weapon
|
|
FVector ImpulseDirection = MeshRight.RotateAngleAxis(-20.f, MeshForward);
|
|
|
|
float RandomRotation{ 30.f };
|
|
ImpulseDirection = ImpulseDirection.RotateAngleAxis(RandomRotation, FVector(0.f, 0.f, 1.f));
|
|
ImpulseDirection *= 2000.f;
|
|
GetItemMesh()->AddImpulse(ImpulseDirection);
|
|
|
|
bFalling = true;
|
|
GetWorldTimerManager().SetTimer(ThrowWeaponTimer, this,
|
|
&AWeapon::StopFalling, ThrowWeaponTime);
|
|
|
|
EnableGlowMaterial();
|
|
}
|
|
|
|
void AWeapon::DecrementAmmo()
|
|
{
|
|
if (Ammo - 1 <= 0)
|
|
Ammo = 0;
|
|
else
|
|
--Ammo;
|
|
}
|
|
|
|
void AWeapon::StartSlideTimer()
|
|
{
|
|
bMovingSlide = true;
|
|
GetWorldTimerManager().SetTimer(SlideTimer, this, &AWeapon::FinishMovingSlide, SlideDisplacementTime);
|
|
}
|
|
|
|
void AWeapon::ReloadAmmo(int32 Amount)
|
|
{
|
|
checkf(Ammo + Amount <= MagazineCapacity, TEXT("Attempted to reload with more than the magazine capacity!"))
|
|
Ammo += Amount;
|
|
}
|
|
|
|
bool AWeapon::ClipIsFull()
|
|
{
|
|
return Ammo >= MagazineCapacity;
|
|
}
|
|
|
|
void AWeapon::StopFalling()
|
|
{
|
|
bFalling = false;
|
|
SetItemState(EItemState::EIS_Pickup);
|
|
StartPulseTimer();
|
|
}
|
|
|
|
void AWeapon::OnConstruction(const FTransform& Transform)
|
|
{
|
|
Super::OnConstruction(Transform);
|
|
|
|
const FString WeaponTablePath{ TEXT("/Script/Engine.DataTable'/Game/_Game/DataTable/WeaponDataTable.WeaponDataTable'") };
|
|
UDataTable* WeaponTableObject = Cast<UDataTable>(StaticLoadObject(UDataTable::StaticClass(), nullptr, *WeaponTablePath));
|
|
|
|
if (WeaponTableObject)
|
|
{
|
|
FWeaponDataTable* WeaponDataRow = nullptr;
|
|
switch (WeaponType)
|
|
{
|
|
case EWeaponType::EWT_AssaultRifle:
|
|
WeaponDataRow = WeaponTableObject->FindRow<FWeaponDataTable>(FName("AssaultRifle"), TEXT(""));
|
|
break;
|
|
case EWeaponType::EWT_Pistol:
|
|
WeaponDataRow = WeaponTableObject->FindRow<FWeaponDataTable>(FName("Pistol"), TEXT(""));
|
|
break;
|
|
case EWeaponType::EWT_SubmachineGun:
|
|
default:
|
|
WeaponDataRow = WeaponTableObject->FindRow<FWeaponDataTable>(FName("SubmachineGun"), TEXT(""));
|
|
}
|
|
|
|
if (WeaponDataRow)
|
|
{
|
|
AmmoType = WeaponDataRow->AmmoType;
|
|
Ammo = WeaponDataRow->WeaponAmmo;
|
|
MagazineCapacity = WeaponDataRow->MagazineCapacity;
|
|
SetPickupSound(WeaponDataRow->PickupSound);
|
|
SetEquipSound(WeaponDataRow->EquipSound);
|
|
GetItemMesh()->SetSkeletalMesh(WeaponDataRow->ItemMesh);
|
|
SetItemName(WeaponDataRow->ItemName);
|
|
SetIconItem(WeaponDataRow->InventoryIcon);
|
|
SetIconAmmo(WeaponDataRow->AmmoIcon);
|
|
|
|
SetMaterialInstance(WeaponDataRow->MaterialInstance);
|
|
PreviousMaterialIndex = GetMaterialIndex();
|
|
GetItemMesh()->SetMaterial(PreviousMaterialIndex, nullptr);
|
|
SetMaterialIndex(WeaponDataRow->MaterialIndex);
|
|
|
|
ClipBoneName = WeaponDataRow->ClipBoneName;
|
|
ReloadMontageSection = WeaponDataRow->ReloadMontageSection;
|
|
|
|
GetItemMesh()->SetAnimInstanceClass(WeaponDataRow->AnimBP);
|
|
|
|
CrosshairsMiddle = WeaponDataRow->CrosshairsMiddle;
|
|
CrosshairsLeft = WeaponDataRow->CrosshairsLeft;
|
|
CrosshairsRight = WeaponDataRow->CrosshairsRight;
|
|
CrosshairsBottom = WeaponDataRow->CrosshairsBottom;
|
|
CrosshairsTop = WeaponDataRow->CrosshairsTop;
|
|
|
|
AutoFireRate = WeaponDataRow->AutoFireRate;
|
|
MuzzleFlash = WeaponDataRow->MuzzleFlash;
|
|
FireSound = WeaponDataRow->FireSound;
|
|
|
|
BoneToHide = WeaponDataRow->BoneToHide;
|
|
if (BoneToHide != FName(""))
|
|
{
|
|
GetItemMesh()->HideBoneByName(BoneToHide, EPhysBodyOp::PBO_None);
|
|
}
|
|
|
|
bAutomatic = WeaponDataRow->bAutomatic;
|
|
Damage = WeaponDataRow->Damage;
|
|
HeadshotDamage = WeaponDataRow->HeadshotDamage;
|
|
}
|
|
|
|
if (GetMaterialInstance())
|
|
{
|
|
SetDynamicMaterialInstance(UMaterialInstanceDynamic::Create(GetMaterialInstance(), this));
|
|
GetDynamicMaterialInstance()->SetVectorParameterValue(TEXT("FresnelColor"), GetGlowColor());
|
|
GetItemMesh()->SetMaterial(GetMaterialIndex(), GetDynamicMaterialInstance());
|
|
|
|
EnableGlowMaterial();
|
|
}
|
|
}
|
|
}
|
|
|
|
void AWeapon::BeginPlay()
|
|
{
|
|
Super::BeginPlay();
|
|
|
|
if (BoneToHide != FName(""))
|
|
{
|
|
GetItemMesh()->HideBoneByName(BoneToHide, EPhysBodyOp::PBO_None);
|
|
}
|
|
}
|
|
|
|
void AWeapon::FinishMovingSlide()
|
|
{
|
|
bMovingSlide = false;
|
|
}
|
|
|
|
void AWeapon::UpdateSlideDisplacement()
|
|
{
|
|
if (!SlideDisplacementCurve && !bMovingSlide) return;
|
|
|
|
const float ElapsedTime{ GetWorldTimerManager().GetTimerElapsed(SlideTimer) };
|
|
const float CurveValue{ SlideDisplacementCurve->GetFloatValue(ElapsedTime) };
|
|
|
|
SlideDisplacement = CurveValue * MaxSlideDisplacement;
|
|
RecoilRotation = CurveValue * MaxRecoilRotation;
|
|
}
|