super-duper-spoon/Source/Shooter/Weapon.cpp

141 lines
4.1 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"))
{
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);
}
}
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::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_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;
}
if (GetMaterialInstance())
{
SetDynamicMaterialInstance(UMaterialInstanceDynamic::Create(GetMaterialInstance(), this));
GetDynamicMaterialInstance()->SetVectorParameterValue(TEXT("FresnelColor"), GetGlowColor());
GetItemMesh()->SetMaterial(GetMaterialIndex(), GetDynamicMaterialInstance());
EnableGlowMaterial();
}
}
}